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

时间:2015-06-02 16:02:08

标签: c# .net com 32bit-64bit com-interop

下面的代码在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. 到期 正在运行,并且在第一个代码行obj中收到一个COM对象。但是,第二个代码行引发了InvalidCastException,因为QueryInterfaceHRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)而失败。 (显然,这适用于32位版本。)
  3. 我必须做些什么才能让第二个代码行中的演员成功?

    编辑正如@HansPassant所建议的那样,我启动了ProcessMonitor并监控了32位和64位应用程序。我观察到64位应用程序在执行GetActiveObject(第一代码行)时忽略了访问COM对象特定的dll(CreateFile,QueryBasicInformationFile,QueryNameInformationFile,...),这与32位应用程序相反,即使我' ve事先添加了相应的注册表项,即AppIDDllSurrogate

    Edit1 我删除了我添加的所有注册表项,并仔细检查了结果,包括ProcessMonitor的日志文件。我没有发现任何差异 - 与以前一样的症状。

    更新在第三方软件的目录中,我找到了Due.tlb,我尝试创建一个运行时可调用包装器,如64 to 32 bit Interop - how?中所示。

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

1 个答案:

答案 0 :(得分:0)

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

广告更新

好消息

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

坏消息

未提供承诺的粘合代码,因此64位和32位的桥接无效。 (32位版本的版本和以前一样。)