【发布时间】:2015-08-16 12:54:31
【问题描述】:
下面的代码在 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位应用时的两种情况
-
到期 没有运行,并且第一行代码失败并显示
HRESULT: 0x800401E3 (MK_E_UNAVAILABLE)。 没关系,在 32 位版本中也是如此。 -
到期 正在运行,并且在第一个代码行中
obj接收一个 COM 对象。但是,第二个代码行会抛出一个InvalidCastException,因为QueryInterface失败并显示HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)。 (显然,这适用于 32 位版本。)
问我必须怎么做才能使第二行代码中的演员成功?
编辑 正如@HansPassant 所建议的,我启动了 ProcessMonitor 并监控了 32 位和 64 位应用程序。我观察到 64 位应用程序在执行 GetActiveObject(第一个代码行)时省略了访问特定于 COM 对象的 dll(CreateFile、QueryBasicInformationFile、QueryNameInformationFile,...),而 32 位应用程序却做到了,即使我已经添加了事先对应的注册表项,即AppID,DllSurrogate。
Edit1 我删除了我添加的所有注册表项,并仔细检查了结果,包括 ProcessMonitor 的日志文件。我没有发现任何差异 - 与以前的症状相同。
更新在第 3 方软件的目录中,我找到了 Due.tlb,并尝试按照 64 to 32 bit Interop - how? 中的提示创建运行时可调用包装器。
我用tlbimp.exe Due.tlb /out:Interop.due.dll 创建了一个Interop.due.dll。不幸的是,当我将原来的 32 位 Interop.deu.dll 替换为新创建的与平台无关的解决方案时,我的解决方案无法编译(缺少参考)。
【问题讨论】:
-
嗯,0x80040154 很奇怪。但问题肯定是您没有 64 位版本的代理。使用 SysInternals 的 Process Monitor 获得洞察力。
-
如果您投反对票,请留下评论原因。
-
@HansPassant 我尝试了 ProcessMonitor,请查看我的编辑结果。
-
好吧,这并没有多大帮助。在您的问题中没有提到您手动编辑了注册表并修改了代理是相当犯罪的顺便说一句。你做错了,如果你不描述,没人可能知道你做错了什么。
-
@HansPassant 记住我在原始帖子中引用的两个链接,这就是我试图让事情顺利进行的原因。
标签: c# .net com 32bit-64bit com-interop