我有一个解决方案,可以在我的开发机器上编译并与传统的COM对象进行互操作。
当我通过ClickOnce部署应用程序(或手动将bin目录内容复制/粘贴到VM)时,我得到以下内容:
无法将“System .__ ComObject”类型的COM对象强制转换为接口 输入'DBCCTRLLib.IHistory'。此操作失败,因为 QueryInterface在具有IID的接口的COM组件上调用 '{5CD1A1BC-1837-11D3-84CE-0090272DBE04}由于以下原因而失败 错误:不支持此类接口(HRESULT异常:0x80004002 (E_NOINTERFACE))。
当我尝试从之前没有使用的COM对象调用特定的功能时会发生这种情况。所有事先与COM / ActiveX功能正确互操作而没有问题。
我很难过,因为我不知道如何从这里开始 - 我是一名COM互操作新秀。它在我的开发机器上运行正常,将其移动到VM或通过ClickOnce部署导致上述故障。
Interop.DBCCTRLLib.dll设置为隔离。 AxDBCCTRLLib.dll只是默认设置(通过工具箱添加到WinForm时自动生成)。
“没有这样的界面支持”让我觉得我有某种dll不匹配,但我不知道在哪里/什么/如何检查。
[编辑:12/3/2013]我已经清理了所有遇到的DLL系统,并为所有VM测试环境做了同样的事情。我能够运行一个只需访问COM对象并成功执行查询的测试项目。我可以将此测试项目复制到VM,它可以工作。如果我对我的主项目解决方案做同样的事情,它会像以前一样失败。我已经验证了所讨论的所有DLL在两个项目之间完全相同 - 一个工作,一个不工作。两个项目以完全相同的方式引用COM对象,尽管主项目确实在新的STA线程上启动了COM对象。
答案 0 :(得分:2)
E_NOINTERFACE有两个基本原因:
DLL Hell,您运行的组件版本与编译程序的版本不同。当原作者修改IHistory接口时,会发生这种情况,并且根据COM的要求,修改了接口的guid。因此,您的程序要求使用旧接口(5CD1A1BC-1837-11D3-84CE-0090272DBE04),但它已不存在了。
Threading Hell,你在一个与创建原始COM对象的线程不同的线程上调用IHistory方法。 COM寻找一种方法来编组调用以保持组件线程安全但无法找到代理/存根来完成工作。作为最后一次喘息,它将查询IMarshal并且也没有实现(它很少),所以它放弃了E_NOINTERFACE的幽灵。可能是因为您忘记复制代理/存根DLL,可能是因为该组件根本不支持它。
这些只是让你开始寻找正确的角落的提示,不足以钉牢它。如果您发布了生成的.manifest文件的内容,那将会有很大帮助。 threadingModel,typelib和comInterfaceExternalProxyStub元素在第二个项目符号中起着重要作用。联系组件的作者寻求支持是非常明智的。