Re: Creating a COM object
- From: "Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx>
- Date: Wed, 6 Jul 2005 20:56:10 +0200
Carlos,
I'm getting the impression that you are doing all this from the command line
instead of from within VS, please correct me if I'm wrong. The ActiveX DLL
is a VB6 ActiveX "usercontrol" type of dll (OCX) right?
When using the command line tools did you create the interop assembly using
aximp.exe or did you use tlbimp.exe. Note that you should use the former!
And don't forget that hosting OCX requires a valid control host, windows
forms are valid hosts, but console applications and services aren't!!!
Willy.
"Carlos Lozano" <CarlosLozano@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:DDF7EABC-A800-4125-91E4-66ED277856B9@xxxxxxxxxxxxxxxx
> Hi Willy,
>
> Here is the code per your request.
> I just used the same command as in vbscript.
>
> I created an empty class and added the following function.
> Public Function CreateInstance(ByVal sComponentID As String) As Object
> Set CreateInstance = CreateObject(sComponentID)
> End Function
>
> compiled into a dll. Registered the DLL.
>
> Then added a reference to the C# code and another class to derive from it
> as
> below:
>
> using MTMicrImage; // This is the reference to the OCX interop
> using vbMicrImage; // reference to the VB6 DLL and created an interop
> assembly
>
> namespace MTMicrImage
> {
> /// <summary>
> /// Summary description for _oMicrImage.
> /// </summary>
> ///
>
> // Inherits from the VB6 Interop
> internal class ovbMicrImage : vbMicrImage.vbMTMicrImageClass,
> vbMicrImage.vbMTMicrImage
> {
> public ovbMicrImage()
> {
> }
> }
>
> // inherits all interfaces from the OCX interop
> internal interface __oMicrImage : MTMicrImage.MicrImage,
> MTMicrImage._MicrImage,
> MTMicrImage.__MicrImage,
> MTMicrImage.__MicrImage_Event
> {
>
> }
>
> // Inherits from above interface
> public class _oMicrImage : MTMicrImage.__oMicrImage
> {
> // This line caused the accessibility
> problem
> // private MTMicrImage.MicrImageClass obase = new
> MicrImageClass();
>
> // Created an instance of the VB6 interop
> class
> private ovbMicrImage ovbMicrImage = new ovbMicrImage();
> private bool lDataReceived = false;
>
> public _oMicrImage()
> {
>
> // This is the ClsId registration
> of the OCX file, not the
> // interop.
> string sComponent = "MTMicrImage.MicrImage";
> try
> {
> // Passed the ClsId to the vb6 class and cast it to the OCX interop class
> obase =
> (MTMicrImage.MicrImageClass)
> ovbMicrImage.CreateInstance(sComponent);
> }
> catch (Exception e)
> {
> MessageBox.Show("Can not create instance of component " + sComponent +
> "\n" + e.ToString());
> }
> }
>
> // Implementation of all methods and
> properties goes here
> public string sStatus
> {
> get
> {
> return obase.sStatus;
> }
> set
> {
> obase.sStatus = value;
> }
> }
>
> public void reset()
> {
> obase.reset();
> }
>
> // and so on....
> // Removed the other implementations
> }
> }
>
> This completes the wrapping.
>
> Then I just create an instance of _oMicrImage in my main application.
>
> What do you think?
>
> Carlos Lozano
> www.caxonline.net
> "Willy Denoyette [MVP]" wrote:
>
>> I would like to see how you managed to create an instance of a
>> non-creatable
>> class from another DLL, this is simply not possible, so I guess you are
>> creating another class. Would you mind to post the oleview output of the
>> OCX
>> assembly.
>>
>> Willy.
>>
>> "Carlos Lozano" <CarlosLozano@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
>> news:6353B988-FF8D-47FF-A3FB-E40ACE9905F4@xxxxxxxxxxxxxxxx
>> > Hi Willy.
>> >
>> > I really appreciate you have taken the time to helping me with this. I
>> > just
>> > found an alternate "hybrid" solution (part in VB6, part c#), but will
>> > be
>> > looking into your last suggestion as I prefer a 100% c# solution.
>> >
>> > Description:
>> > I found the OCX was developed using VB6 (using the object viewer in
>> > VB6).
>> > As it was not possible to create the instance in .NET (I tried C#.NET,
>> > VB.NET), I decided to create it using VB6.
>> >
>> > The hybrid solution is as follows:
>> > 1) Creating a a DLL module using a VB6 class to create the instance as
>> > an
>> > object
>> > 2) Passing the object instance to the C# class and cast it with the
>> > class
>> > derived from the interop interface.
>> >
>> > It seems to be working okay.
>> >
>> > Thank you,
>> >
>> > Carlos Lozano
>> >
>> > "Willy Denoyette [MVP]" wrote:
>> >
>> >> Inline
>> >>
>> >> Willy.
>> >>
>> >> "Carlos Lozano" <CarlosLozano@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in
>> >> message
>> >> news:A145C35A-60C8-4CB1-B9CE-BE0DBF466655@xxxxxxxxxxxxxxxx
>> >> >I have copied part of the class declaration for your review.
>> >> > In fact the declaration of the constructor seems to be the problem
>> >> > as
>> >> > below.
>> >> >
>> >> > .method assembly specialname rtspecialname
>> >> > instance void .ctor() runtime managed internalcall
>> >> > {
>> >> > }
>> >> >
>> >> > it is "internalcall" which makes it inaccesible.
>> >> >
>> >> No, its not! Don't mess with this, "internalcall" means that the CLR
>> >> is
>> >> called to contruct the RCW.
>> >> The problem is ".method assembly" ... , this means that the class is
>> >> not
>> >> meant to be created from outside the Control code, if this class is
>> >> authored
>> >> using VB6, it means that the class 'instancing' attribute is set to
>> >> PublicNotCreatable (the default when using the Class wizard in a VB
>> >> Control
>> >> project), which translates into assembly (or internal in C#).
>> >>
>> >> > I tired changing it to:
>> >> > //.method assembly specialname rtspecialname
>> >> > .method public specialname rtspecialname
>> >> > instance void .ctor() runtime managed internalcall
>> >> > {
>> >> > }
>> >> >
>> >> > and:
>> >> > //.method assembly specialname rtspecialname
>> >> > .method public specialname rtspecialname
>> >> > instance void .ctor() runtime managed
>> >> > {
>> >> > }
>> >> >
>> >> > but give different kind of problems, so I went back to the original
>> >> > interop
>> >> > file.
>> >> >
>> >>
>> >> Not supprisingly.
>> >>
>> >> > In the object browser the clas constructor shows to be public.
>> >> >
>> >> > In addition, as mentioned before I can create an instance of the
>> >> > class
>> >> > using
>> >> > javascript. The only difference is javascript creates it directly
>> >> > from
>> >> > the
>> >> > OCX file, c# uses the interop assembly. I think the problem is in
>> >> > the
>> >> > interop
>> >> > assembly.
>> >> >
>> >> No the problem is that you are trying to create a non creatable
>> >> object.
>> >> Take
>> >> a look at your ocx file using oleview.exe , you will notice that the
>> >> class
>> >> interface you are trying to create from C# is marked "noncreatable".
>> >> So I
>> >> guess you are mixing things up and you do create a different class
>> >> using
>> >> vbs
>> >> or Jscript.
>> >>
>> >>
>> >> > I also tried creating it manually.
>> >> > used:
>> >> > 1) tlbimp // imported the OCX file into the interop file.
>> >> > 2) ildasm // Created IL code
>> >> > 3) ilasm // recompiled as dll.
>> >> >
>> >>
>> >> OCX are activeX controls, you should use aximp instead of tlbimp.
>> >>
>> >> > Thank you,
>> >> >
>> >> > Carlos
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>
.
- References:
- Creating a COM object
- From: Carlos Lozano
- Re: Creating a COM object
- From: Bob Powell [MVP]
- Re: Creating a COM object
- From: Carlos Lozano
- Re: Creating a COM object
- From: Willy Denoyette [MVP]
- Re: Creating a COM object
- From: Carlos Lozano
- Re: Creating a COM object
- From: Willy Denoyette [MVP]
- Re: Creating a COM object
- From: Carlos Lozano
- Re: Creating a COM object
- From: Willy Denoyette [MVP]
- Re: Creating a COM object
- From: Carlos Lozano
- Re: Creating a COM object
- From: Willy Denoyette [MVP]
- Re: Creating a COM object
- From: Carlos Lozano
- Creating a COM object
- Prev by Date: RE: Security of C# dll
- Next by Date: Re: Detect when a workstation is locked
- Previous by thread: Re: Creating a COM object
- Next by thread: unable to get installer types
- Index(es):
Relevant Pages
|