在 64 位环境中使用 32 位 COM 对象

本文关键字:COM 对象 环境 | 更新日期: 2023-09-27 17:52:50

下面的代码在 32 位 c# 应用程序中执行没有问题。

 object obj = system.Runtime.InteropServices.Marshal.GetActiveObject("Due.Application");
 var due = (Due.IDueApplication2)obj;

现在,我尝试让相同的代码在 64 位 c# 应用程序中工作,因此我按照

http://www.gfi.com/blog/32bit-object-64bit-environment/或 http://www.codeproject.com/Tips/267554/Using-bit-COM-Object-from-bit-Application

运行 64 位应用程序时的两种情况

  1. 到期运行,第一个代码行失败并显示 HRESULT: 0x800401E3 (MK_E_UNAVAILABLE)这很好,在 32 位版本中也会发生。
  2. Due正在运行,在第一个代码行中obj接收一个 COM 对象。但是,第二个代码行抛出InvalidCastException QueryInterface因为HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)失败。(显然,这适用于 32 位版本。

Q 我必须怎么做才能使第二行代码中的演员表成功?

编辑 按照@HansPassant的建议,我启动了ProcessMonitor并监视了32位和64位应用程序。我观察到 64 位应用程序在执行 GetActiveObject(第 1 行代码(时省略了访问 COM 对象特定的 dll(CreateFile、QueryBasicInformationFile、QueryNameInformationFile 等(,相比之下,32 位应用程序这样做了,即使我事先添加了相应的注册表项,即 AppIDDllSurrogate

编辑1我删除了我添加的所有注册表项,并仔细检查了结果,包括进程监视器的日志文件。我没有注意到任何差异 - 与以前相同的症状。

更新 在第三方软件的目录中,我找到了一个Due.tlb,并尝试创建一个运行时可调用包装器,如 64 到 32 位互操作中提示的那样 - 如何?

我用tlbimp.exe Due.tlb /out:Interop.due.dll创建了一个Interop.due.dll.不幸的是,当我用新创建的与平台无关的 32 位Interop.deu.dll替换时,我的解决方案无法编译(缺少引用(。

在 64 位环境中使用 32 位 COM 对象

唯一有效的是进程外解决方案。我实现了一个 32 位 WCF 服务,该服务提供对 64 位进程的 COM 对象的访问。(因此,我自己实现了代理。

广告更新

好消息

通过利用这篇文章中的信息,我能够重新生成Interop.due.dll的平台不可知版本。尽管如此,TlbImp.exe警告我 TI3002 :将类型库导入与平台无关的程序集。 如果类型库不是真正与平台无关的,则这可能会导致错误。

坏消息

没有提供承诺的胶水代码,因此 64 位和 32 位的桥接没有成功。(仅 32 位版本像以前一样工作。