C#包装器接口错误:E_NOINTERFACE

我正在尝试为我拥有的COM对象(名为SC_COM.dll)生成一个C#包装器,但是在将它与Visual Studio 2008(运行Vista)链接时遇到了一些问题。 我需要使用COM DLL免费注册 – 我使用清单文件让Visual Studio了解SC_COM.dll,这似乎有效。 我使用TblImp.exe生成我在Visual Studio 2008中引用的类型库(SC_COMtlb.dll),因此我可以使用我需要的DLL进行早期绑定。 DLL与清单和可执行文件位于同一目录中。

这是问题:当我实例化对象并尝试在C#中调用其中一个方法时,它会抛出以下错误:

检测到错误:无法将类型为“SC_COMtlb.SCAccessObjClass”的COM对象强制转换为接口类型“SC_COMtlb.ISCUploader”。 此操作失败,因为对IID为“{C677308A-AC0F-427D-889A-47E5DC990138}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULTexception:0x80004002(E_NOINTERFACE)) 。

我不完全确定这个错误意味着什么 – 我已经对错误代码进行了搜索,而且它似乎是一个相对普遍的C#错误。 所以我要在这里以错误的方式链接COM对象,还是有一些其他重要的步骤我可能会丢失?

我应该注意到,我不完全确定我生成的类型库(S \ C_COMtlb.dll)如何知道实际COM DLL的位置,因为它没有在系统中注册 – 我认为它只是看起来相同目录。 这可能是问题,如果是这样,我怎样才能更好地将这两者联系起来?

尝试将此添加到您的App.exe.manifest:

 

可以从Visual Studio生成的Native.Namespace.Assembly.Name.manifest中找到TLBID,如下所示:

  

很长一段时间我一直在反对这个问题,但是我找到了这些有用的参考资料并将它拼凑在一起,它对我有用:

  • 为什么在创建支持该接口的对象时会获得E_NOINTERFACE?
  • 免注册Skype4Com和multithreading公寓
  • COM组件的免注册激活:演练

错误代码意味着Visual Studio 认为某个对象应该实现某个接口,但是当我尝试“连接”到该接口时,该对象会响应它不知道它。

我猜这个问题出在SC_COM.dll中。 TLBIMP.EXE从存储在DLL中的元数据中提取类和接口信息,并为该类构建包装器。

例如,如果SC_COM是用C ++编写的,如果DLL的创建者在IDL文件中指示某个类实现了该接口,但实际代码不支持该接口,则可能会发生这种情况。

这是此DLL可能存在的另一个常见问题来源:有时您有一个实现ISomething2接口的类,该接口派生自ISomething接口,但类实现只能识别ISomething2。 如果实现派生接口,则还必须识别其基接口。 这是一个常见的错误。

你有(并控制)DLL的源代码吗?

哪个版本的Windows? 从Windows Vista开始,内部清单会覆盖外部清单。 默认情况下,C#可执行文件具有内部清单,这意味着将忽略您的whatever.exe.manifest文件。

如果你转到C#EXE的属性页面,你会看到“应用程序选项卡”上有一个“图标和清单”部分。 将“Manifest”设置为清单文件的名称,它将被嵌入而不是默认文件。

如果这不起作用,您可能必须使用MT.EXE执行一些后构建步骤,以便将外部清单与默认内部清单合并,并将合并后的清单放回到.EXE文件中。