tags:

views:

43

answers:

2

I have a very old (VC++ 5.0) proprietary DLL which I need to use from C# (Visual Studio 2010). The example specifies that to access this component I need to call CreateDispatch("application") which indicates towards OLE.

The following is the example code (C++):

IComponentServer Server;
Server.CreateDispatch("Component.Server");

I added a Reference through Visual Studio to the TLB file I have, and I can import its namespace successfully, but IComponentServer does not have any method called CreateDispatch.

What is the right approach to create the instance of an OLE component through C#?

+1  A: 

MFC's CreateDispatch creates COM objects based on a CLSID or ProgId string. You can instantiate COM objects directly from C# code.

Assuming the Visual Studio reference gives you Interop.Component.dll:

IComponentServer server = new Interop.Component.ServerClass();
Tim Robinson
Might not work, the MFC code was using the late-bound IDispatch interface. Not so easy to do in C# unless the OP uses version 4.0 and can leverage *dynamic*. A little adapter written in VB.NET would be an option.
Hans Passant
This may be the only option - as per @JaredPar's answer, the type library doesn't look too great.
Tim Robinson
@Tim Can you explain where did the Interop package come from? A bit lost here with this.
jbx
@jbx Visual Studio generates it when you add a TLB reference. The fact that you can import its namespace suggests the interop is fine. However, your InvalidCastException suggests that the TLB itself isn't reliable.
Tim Robinson
@Tim Thanks, now I understood what you were referring to. Actually you can't really (at least in my case) instantiate the ServerClass directly (it says it Interop type cannot be embedded, use the applicable interface). However the interface IComponentServer has a [CoClass] attribute which refers to the COM class to be instantiated. So with some tweaks your suggestion should work.
jbx
+1  A: 

If you have either the CLSID or ProgID you can use the following set of methods.

var type = Type.GetTypeFromProgID(progIdString);
var obj = Activator.CreateInstance(type);
var server = (IComponentServer)obj;
JaredPar
Thanks JaredPar.Any idea why I might be getting an InvalidCastException with the code you provided?This operation failed because the QueryInterface call on the COM component for the interface with IID '{BAA135B2-F931-11D0-9C14-0060973155F0}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
jbx
@jbx, most likely cause is the type libraries for the COM assembly aren't registered properly.
JaredPar
I tried regasm which failed saying that it is not a valid .Net assembly (rightly so, this is an old library from the ages of VC++ 5.0)I tried regtlibv12.exe which said that it registered the TLB successfully. However same problem. Any ideas what I could do?
jbx