C# wrapper interface error: E_NOINTERFACE

DashRantic picture DashRantic · Jun 1, 2009 · Viewed 10.5k times · Source

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?

Answer

Chris Benard picture Chris Benard · Jun 29, 2009

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: