下面的代码在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位应用程序相反,即使我' ve事先添加了相应的注册表项,即AppID
,DllSurrogate
。
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
时,我的解决方案无法编译(缺少引用)。
答案 0 :(得分:0)
唯一有效的是进程外解决方案。我实现了一个32-bit WCF-service,它提供了对64位进程的COM对象的访问。 (因此,我自己实现了代理。)
广告更新
好消息
通过利用此post中的信息,我能够重新生成Interop.due.dll
的平台无关版本。尽管如此,TlbImp.exe
警告我警告TI3002:将类型库导入平台无关组件。如果类型库不是真正与平台无关的,这可能会导致错误。
坏消息
未提供承诺的粘合代码,因此64位和32位的桥接无效。 (32位版本的版本和以前一样。)