tags:

views:

779

answers:

3

I am trying to produce a C# wrapper for a COM object that I have (named SC_COM.dll), but am having some issues linking it with Visual Studio 2008 (running Vista). I need to do this registration-free with the COM DLL--I'm using a manifest file to let Visual Studio know about SC_COM.dll, and that appears to be working. I used TblImp.exe to generate a type library (SC_COMtlb.dll) that I'm referencing in Visual Studio 2008 so I can do early binding with the DLL that I need. The DLLs are both in the same directory as the manifest and the executable.

Here's the issue: When I instantiate the object and try and call one of its methods in C#, it throws the following error:

Error detected: Unable to cast COM object of type 'SC_COMtlb.SCAccessObjClass' to interface type 'SC_COMtlb.ISCUploader'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{C677308A-AC0F-427D-889A-47E5DC990138}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

I'm not entirely certain what this error means--I've done a search on the error code, and it appears to be a relatively general C# error. So am I going about linking the COM object the wrong way here, or is there some other important step I may be missing?

I should probably note that I'm not entirely sure how the type library (S\C_COMtlb.dll) that I produced knows where the actual COM DLL is, since it's not registered with the system--I assume it just looks in the same directory. Could this potentially be the issue, and if so, how can I better link the two?

A: 

Which version of Windows? Since Windows Vista, an internal manifest overrides an external manifest. By default, C# executables have internal manifests, which means that your whatever.exe.manifest file will be ignored.

If you go to the properties page for your C# EXE, you'll see there's an "Icon and manifest" section on the "Application tab". Set "Manifest" to the name of your manifest file, and it'll be embedded instead of the default one.

If that doesn't work, you might have to do some post-build steps with MT.EXE in order to merge your external manifest with the default internal one and to put the merged manifest back into the .EXE file.

Roger Lipscombe
I'm working with Vista here. The correct manifest seems to be set under Applications->Icon and Manifest. Do you have any suggestions/any other links to reference for the post-build steps you mentioned? Thanks :-)
DashRantic
+1  A: 

the error code means that Visual Studio thinks that a certain object is supposed to implement a certain interface, but when I tries to "connect" to that interface the object responds that it doesn't know about it.

I would guess that the problem is in SC_COM.dll. TLBIMP.EXE extracts class and interface information from metadata stored within the DLL and builds wrappers for the class.

For example, if SC_COM is written in C++, this could happen if the creator of the DLL indicated in the IDL file that a class implements that interface, but the actual code doesn't support that interface.

Here's another common source of problems this DLL might have: sometimes you have a class implementing an ISomething2 interface which derives from an ISomething interface, but the class implementation to only recognize ISomething2. If you implement a derived interface, you must recognize its base interface as well. This is a common mistake.

Do you have (and control) the source code for the DLL?

Euro Micelli
+2  A: 

Try adding this to your App.exe.manifest:

<comInterfaceExternalProxyStub 
  name="ISCUploader" 
  iid="{C677308A-AC0F-427D-889A-47E5DC990138}"
  proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
  baseInterface="{00000000-0000-0000-C000-000000000046}"
  tlbid = "{PUT-YOUR-TLB-GUID-HERE}" />

Where TLBID can be found from your Visual Studio generated Native.Namespace.Assembly.Name.manifest, looking like this:

<typelib tlbid="{A-GUID-IS-HERE--USE-IT}"
  version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />

I was banging my head against this for quite some time, but I found these helpful references and pieced it together and it's working for me:

Chris Benard