在 64 位环境中使用 32 位 COM 对象 [英] Using a 32bit COM-object in a 64bit environment

查看:33
本文介绍了在 64 位环境中使用 32 位 COM 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The code below executes without problems in a 32bit c#-application.

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

 var due = (Due.IDueApplication2)obj;

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

Now, I try to get the same code working in a 64bit c#-application and therefore I followed the instructions at

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

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

Two cases when running the 64bit application

  1. 到期 运行,并且第一行代码失败并显示 HRESULT: 0x800401E3 (MK_E_UNAVAILABLE).没问题并且在 32 位版本中也会发生.
  2. 到期 正在运行并且在第一个代码行 obj 接收一个 COM 对象.但是,第二个代码行会抛出一个 InvalidCastException,因为 QueryInterface 失败并返回 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG).(显然,这适用于 32 位版本.)
  1. Due is not running and the first code-line fails with HRESULT: 0x800401E3 (MK_E_UNAVAILABLE). That's fine and happens in the 32bit version as well.
  2. Due is running and in the first code-line obj receives a COM-object. But then, the second code-line throws an InvalidCastException because QueryInterface fails with HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG). (Obviously, this works in the 32bit version.)

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

Q What must I do, to make the cast in the 2nd code-line to succeed?

编辑 根据@HansPassant 的建议,我启动了 ProcessMonitor 并监控了 32 位和 64 位应用程序.我观察到 64 位应用程序在执行 GetActiveObject(第一个代码行)时省略了访问 COM 对象特定的 dll(CreateFile、QueryBasicInformationFile、QueryNameInformationFile 等),相比之下,32 位应用程序甚至尽管我事先添加了相应的注册表项,即 AppIDDllSurrogate.

Edit As suggested by @HansPassant, I fired up the ProcessMonitor and monitored both the 32bit and 64bit application. I observed that the 64bit application when executing GetActiveObject (1st code-line) omitted accessing a COM-object specific dll (CreateFile, QueryBasicInformationFile, QueryNameInformationFile, ...) which in contrast the 32bit application did, even though I've added the according registry entries beforehand, i.e. AppID, DllSurrogate.

Edit1 我删除了我添加的所有注册表项,并仔细检查了结果,包括 ProcessMonitor 的日志文件.我没有注意到任何不同 - 与以前相同的症状.

Edit1 I removed all the registry-entries I added and double-checked the results including the log-files of the ProcessMonitor. I didn't notice any difference - same symptoms as before.

更新 在第 3 方软件的目录中,我发现了一个 Due.tlb 并且我尝试按照 64 到 32 位互操作 - 如何?.

Update In the directory of the 3rd party software I found a Due.tlb and I tried to create a runtime-callable-wrapper as hinted in 64 to 32 bit Interop - how?.

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

I created an Interop.due.dll with tlbimp.exe Due.tlb /out:Interop.due.dll. Unfortunately, when I replaced the original 32-bit Interop.deu.dll with the newly created platform-agnostic one my solution failed to compile (missing references).

推荐答案

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

The only thing which worked was an out-of-process solution. I implemented a 32-bit WCF-service which provides the access to the COM-objects for the 64-bit process. (Hence, I implemented the proxy myself.)

广告更新

好消息

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

By utilizing the information in this post I was able to regenerate a platform agnostic version of the Interop.due.dll. Even though, TlbImp.exe warned me with warning TI3002 : Importing a type library into a platform agnostic assembly. This can cause errors if the type library is not truly platform agnostic.

坏消息

未提供承诺的胶水代码,因此无法桥接 64 位和 32 位.(只有 32 位的版本像以前一样工作.)

The promised glue code was not provided and therefore the bridging of 64bit and 32bit did not work out. (The 32bit only version worked as before.)

这篇关于在 64 位环境中使用 32 位 COM 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆