【问题标题】:TYPE_E_CANTLOADLIBRARY - COM interop via MTA threadTYPE_E_CANTLOADLIBRARY - 通过 MTA 线程的 COM 互操作
【发布时间】:2012-05-15 21:17:42
【问题描述】:

我有一个简单的以 x86 为目标的 .NET 3.5 控制台程序,它通过互操作调用 ActiveX DLL 中 COM 对象的方法。在我的注册表中,ActiveX DLL 有一个 Apartment 的 ThreadingModel。当 .NET 程序在 STA 线程中运行时,一切正常。在 MTA 线程中,一些 COM 方法运行良好,其他给我:

System.InvalidCastException:无法将“MyComTypeClass”类型的 COM 对象转换为接口类型“_MyComType”。此操作失败,因为 IID 为“{[省略]}”的接口的 COM 组件上的 QueryInterface 调用失败,原因是以下错误:加载类型库/DLL 时出错。 (来自 HRESULT 的异常:0x80029C4A (TYPE_E_CANTLOADLIBRARY))。

如果我将 ActiveX DLL 的 ThreadingModel 切换为 Free 或 Both,.NET 程序在 MTA 线程中工作,但我想将 ThreadingModel 保留在 Apartment。

具有相同 ActiveX DLL 和互操作程序集的相同 .NET 程序可以在使用两种线程模型的多台其他计算机(WinXP 32 位、Win7 64)上正常工作。该异常仅发生在一台 PC (Win7 64) 上,并且仅发生在 MTA 线程中。有人知道为什么吗?

类似的问题已经被问到没有解决方案,希望第三次是一个魅力:

COM Exception - TYPE_E_CANTLOADLIBRARY?

TYPE_E_CANTLOADLIBRARY when using a COM object on a separate thread on Windows 2003 x64 only

谢谢!

【问题讨论】:

  • 既然你似乎在问为什么,而不是如何让它变得更好,请参阅Explaining STA and MTA。我认为 “一旦在公寓中初始化,在其运行期间就是该公寓的一部分” 位回答了这个问题。
  • 您还可以查看Interop Marshaling 以获取有关编组和 COM 单元的更多信息,特别是 COM 编组器在使用 MTA 时如何参与,这可能解释了您的演员表问题。

标签: c# com-interop


【解决方案1】:

使用来自 MTA 线程的 STA 对象需要编组。标准编组需要类型库。您收到的错误意味着无法加载类型库。

所以我猜想类型库没有正确注册。尝试注销并重新注册 DLL,否则尝试使用 REGTLB.exe 直接注册类型库

【讨论】:

  • 感谢您的回答。我取消/重新注册了 DLL 并直接注册了类型库。我在注册表中看到具有预期 IID 的接口和 typelib,我可以在 OLE/COM 对象查看器中打开 typelib 而不会出现问题。还是不行!
  • 这不是唯一的配置,起点是 HKCR\Interface,它在其中查找 ProxyStubClsId 和 TypeLib 键。使用 SysInternals 的 ProcMon 来查看它搜索这些键。
  • 在 ProcMon 的帮助下修复。谢谢你的提示。 ActiveX DLL 引用了一个类型库注册不正确的第 3 方组件,而这个类型库是必需的,因为正如 Ben 所说,我在线程模型之间进行编组。
猜你喜欢
  • 2017-04-28
  • 2013-08-15
  • 2011-02-21
  • 1970-01-01
  • 2011-02-25
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多