COM Interop Issues

B

Brendan

I have a legacy COM/ActiveX component (an OCX) that I need
to interface with from C# and the .NET framework.

Ordinarily, I would just add a reference to the OCX or add
it to the Toolbox (both of which work in their own ways),
but I need more control over the interfacing, and to that
end I am trying to write my own wrapper class, based on
what the IDE turns out, unfortunately all attempts have
failed.

Here is what I know so far:

When added as an ActiveX component to the Toolbox, I can
interface with it without problem, if I try to import it
as a standard COM component by adding a reference in the
Solution Explorer, I am able to create a new instance of
the object, but immediately after I call any method of the
component I get a COMException style unhandled exception
with the telling additional information of
simply "Catastrophic failure".

What strikes me as odd is that when adding the component
to the toolbar, both an ActiveX wrapper, as well as the
COM wrapper are built and this latter wrapper is identical
to the wrapper built when I simply add a reference. Like
the original, when I use it I get the 'catastrophic
failure message', despite the fact that the ActiveX
wrapper also uses the COM wrapper for it's interfacing to
the OCX.

Needing more control over the actual interface of the
wrapper, I started building my own from scratched based on
the code generated by the earlier steps and the .NET
Reflector. Unfortunately I am not even able to instantiate
this class. Should I try to do so I receive a
COMException, with the additional information of "COM
object with CLSID {0ABFE4A5-75E8-4268-9FBF-30F092863F4A}
is either not valid or not registered."

I have verified that the above CLSID (aka GUID) is that of
the OCX I am trying to interface with and that it is
properly installed and registered on the system.

The class name its self is defined as:

[ComImport, Guid("0ABFE4A5-75E8-4268-9FBF-30F092863F4A"),
TypeLibType((short) 0x1010)]
public class MyOCXTestClass


And it's methods all look very similar to the following:

[PreserveSig, MethodImpl
(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime), DispId(0x3e)]
public virtual extern void Versions(ref int Ocx, ref
int Driver, ref int ChipVersion);

I am looking for a way to fix my existing wrapper class
(the one I have written in code) so that it is able to
properly interface with the OCX in question. Unfortunately
using the IDE's automatic wrappers will not do the job for
me as I will later be using several other OCX's with
nearly identical interfaces and will need to be able to
build a simple C# interface for them all (a job that is
far easier than the current issue).

I am at a loss as to what is causing these issues and hope
someone here has an idea that might fix this problem.
 
N

Nicholas Paldino [.NET/C# MVP]

Brendan,

I don't quite understand what you really need here. COM interop will
provide you with all of the interface definitions that are implemented on
the type, and you should be able to get direct access to the ActiveX control
through the GetOcx method on the wrapper that is created for your control.
Once you have that, you should be able to cast it to any interface that the
control implements (including your own), and do what you wish with it.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Brendan said:
I have a legacy COM/ActiveX component (an OCX) that I need
to interface with from C# and the .NET framework.

Ordinarily, I would just add a reference to the OCX or add
it to the Toolbox (both of which work in their own ways),
but I need more control over the interfacing, and to that
end I am trying to write my own wrapper class, based on
what the IDE turns out, unfortunately all attempts have
failed.

Here is what I know so far:

When added as an ActiveX component to the Toolbox, I can
interface with it without problem, if I try to import it
as a standard COM component by adding a reference in the
Solution Explorer, I am able to create a new instance of
the object, but immediately after I call any method of the
component I get a COMException style unhandled exception
with the telling additional information of
simply "Catastrophic failure".

What strikes me as odd is that when adding the component
to the toolbar, both an ActiveX wrapper, as well as the
COM wrapper are built and this latter wrapper is identical
to the wrapper built when I simply add a reference. Like
the original, when I use it I get the 'catastrophic
failure message', despite the fact that the ActiveX
wrapper also uses the COM wrapper for it's interfacing to
the OCX.

Needing more control over the actual interface of the
wrapper, I started building my own from scratched based on
the code generated by the earlier steps and the .NET
Reflector. Unfortunately I am not even able to instantiate
this class. Should I try to do so I receive a
COMException, with the additional information of "COM
object with CLSID {0ABFE4A5-75E8-4268-9FBF-30F092863F4A}
is either not valid or not registered."

I have verified that the above CLSID (aka GUID) is that of
the OCX I am trying to interface with and that it is
properly installed and registered on the system.

The class name its self is defined as:

[ComImport, Guid("0ABFE4A5-75E8-4268-9FBF-30F092863F4A"),
TypeLibType((short) 0x1010)]
public class MyOCXTestClass


And it's methods all look very similar to the following:

[PreserveSig, MethodImpl
(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime), DispId(0x3e)]
public virtual extern void Versions(ref int Ocx, ref
int Driver, ref int ChipVersion);

I am looking for a way to fix my existing wrapper class
(the one I have written in code) so that it is able to
properly interface with the OCX in question. Unfortunately
using the IDE's automatic wrappers will not do the job for
me as I will later be using several other OCX's with
nearly identical interfaces and will need to be able to
build a simple C# interface for them all (a job that is
far easier than the current issue).

I am at a loss as to what is causing these issues and hope
someone here has an idea that might fix this problem.
 
B

Brendan

Thanks for the prompt reply Nicholas, unfortunately
typecasting will work in a very limited sense because the
common interfaces required are not defined within the COM
components themselves, let me try to explain this better.

We'll call my current component Foo. Later, I will need to
access a second component called Bar. Both Foo and Bar
have very similar interfaces, ideally they would have
inherited from the same interface to begin with, but
because of their history that is not possible.

What I want to be able to do is write a custom COM wrapper
for each, and have both wrappers inherit from the same
interface so that I can create an instance of Foo or Bar,
and not care which it is.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top