为什么在 C# 中实例化 COM 对象会抛出异常

Why does instantiating COM object in C# throw exception

我正在尝试在我用 C# (.net 4.7.2) 编写的测试程序中实例化一个 COM 对象,该对象在用 Borland C++ 编写的 x86 dll 中定义。 COM dll(服务器)正在工作,我有一个 windows 服务也是用 C++ Borland 编写的,可以使用它并从 class(使用 CoCreateInstance)中实例化一个 COM 对象。 dll 已注册并且 InprocServer32 条目具有正确的 dll 路径。 typelib 中不存在 coclass,只有接口(那些存在于 typelib 中)。我已经使用 TlbImp 创建了我在 c# 项目中引用的 dll:s。在项目中,目标平台设置为 x86。我尝试实例化对象的方式是:

var comType = Type.GetTypeFromProgID("ins.MyComType");
object comObj = Activator.CreateInstance(comType);

但是第二行给了我

"Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll" with the message 'Retrieving the COM class factory for component with CLSID {C4363C5E-3831-46DF-8701-60C8D1B612BA} failed due to the following error: 8007007e The specified module could not be found. (Exception from HRESULT: 0x8007007E).".

如果我尝试以管理员身份 运行 应用程序并不重要。我对几年前尝试过类似的事情有一个模糊的记忆,当时它是有效的。它可能在 Win 7 机器上(甚至可能是 32 位系统)。我试图在 DependencyWalker 中打开该项目,但我不确定我在看什么。我收到几个错误:

*Error: At least one required implicit or forwarded dependency was not found. *Error: Modules with different CPU types were found. *Error: A circular dependency was detected. *Warning: At least one delay-load dependency module was not found. *Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

有人知道可能导致异常的原因吗?或者,如果我能得到一些关于如何更深入地研究 dependencywalker 的提示?我得到了一棵巨大的系统装配树,但我看不到任何明显的装配,尽管 DW 将其中许多称为 64 位。我的猜测是某个地方的某些依赖 dll 应该是 x86,但具体是哪一个。是否有类似的 redist 东西我应该安装才能工作?

此致

/埃里克

您应该编写一个包含以下行的简单 VBScript:

set obj = CreateObject("ins.MyComType")
MsgBox TypeName(obj)

将文件命名为 test.vbs

执行命令:

c:\windows\syswow64\wscript.exe test.vbs

使用 syswow64 的版本确保它使用 32 位版本的 wscript.exe,它可以实例化 32 位 COM 对象。 c:\windows\system32 中的版本只能在 DLL 中实例化 64 位进程内 COM 对象...你说你的对象是 32 位 COM DLL 服务器。

如果 vbscript 失败,可能是因为该对象与自动化不兼容——实现了 IDispatch。否则你会收到一条错误消息,说明失败的原因。

如果成功,您将知道 C++ 端可能没有任何问题。您认为是这种情况……但是 Borland C++ 的运行时在哪里?所有东西都是静态链接的,还是其中一些是动态链接的?如果它是动态链接的,它在路径中的什么位置?可能是您拥有的 C++ 服务在其路径中包含该库,因此当它加载您的 COM 对象时,该库可用。但是,当您尝试从 .NET 或 VBScript 等第三方加载时,库的路径就会自行显示。谁知道?我只是提建议。

如果你用ProcMon,它能看出问题出在哪里。它将显示正在读取哪些注册表项以及正在尝试加载哪些文件。