如何从 32 位 Excel 进程实例化 64 位 Class

How to Instantiate a 64-bit Class from 32-bit Excel Process

我已经注册了几个特定于 Unicom Dimensions/IBM SPSS Data Collection Desktop 7 (x64) 软件的 DLL,并验证 类 是否显示在 HKCR/Classes 和 HKLM 下。

Dumpbin.exe 表示以下依赖关系,,我在这里没有看到任何看起来不合时宜的东西,即,没有任何可能未注册的联通软件特定的东西等。

图像具有以下依赖项

KERNEL32.dll
USER32.dll
GDI32.dll
COMDLG32.dll
ADVAPI32.dll
ole32.dll
OLEAUT32.dll
ATL100.DLL
SHLWAPI.dll
MSVCP100.dll
MSVCR100.dll

但是当尝试从 VBA (Excel 2016, 32b) 实例化时失败并显示 429,ActiveX 无法创建对象 :

Dim exp as Object
Set exp = CreateObject("ExportExcel.Export")

我可以从 python (64b 3.7) 实例化:

from win32com import client
exp = client.Dispatch("ExportExcel.Export")

32b Excel 和 64b 维度这么简单吗?

联通的documentation表示这是实例化class的正确方法(示例使用了早期绑定,我都试过了都没有用)。

' ---- Export the Tables ----
    Dim MYEXPORT As ExportExcelLib.Export
    Set MYEXPORT = New ExportExcelLib.Export
    Export MYEXPORT, TableXml, PropertyXml

此外,联通还提供自己的"mrScriptBasic"语言,该语言基于Visual Basic。如您所料,他们还使用 CreateObject 函数来实例化 classes。在他们的脚本软件中,此函数按预期工作并且 returns class.

的正确实例

更新

正如 Noodles 在评论中提到的那样,我试图通过 dllhost 强制它。我 运行 作为管理员的 .bat:

REM _Enable.bat
REM This file merges reg_script.reg using the Reg.exe command.
REM This allows 32b program to call a 64b dll via surrogate
REM It is a per user setting but Regedit doesn't allow non admins to run it
reg import "reg_script.reg"
Pause

这会导入 reg_script.reg 文件,如下所示:

Windows Registry Editor Version 5.00
;reg_script.reg
[HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
@="ExportExcel"
"AppID"="{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}"

[HKEY_CURRENT_USER\SOFTWARE\Classes\Wow6432Node\AppID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"DllSurrogate"=""

[HKEY_CURRENT_USER\SOFTWARE\Classes\AppID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"DllSurrogate"=""

无论我尝试使用 class 名称还是 GUID,错误仍然存​​在。

Windows Registry Editor Version 5.00
;reg_script.reg
[HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"AppID"="{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}"

[HKEY_CURRENT_USER\SOFTWARE\Classes\Wow6432Node\CLSID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"AppID"="{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}"

[HKEY_CURRENT_USER\SOFTWARE\Classes\Wow6432Node\AppID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"DllSurrogate"=""

[HKEY_CURRENT_USER\SOFTWARE\Classes\AppID\{AE2E32FA-FB29-4C42-BFF9-7ACFA1AB0A1B}]
"DllSurrogate"=""

如果 GUID 正确

我遇到了同样的问题,使用以下网页中描述的解决方案解决了这个问题: https://techtalk.gfi.com/32bit-object-64bit-environment/

如果网页不可用,我把它的主要段落复制在这里:

为此,它涉及少量简单的注册表修改:

  • 在 HKey_Classes_Root\Wow6432Node\CLSID[GUID]

  • 找到后添加新的 REG_SZ(字符串)值。名称应为 AppID 和数据应该是您刚刚搜索的相同 COM 对象 GUID 对于

  • 在HKey_Classes_Root\Wow6432Node\AppID下添加一个新密钥\新密钥 应与 com 对象 GUID

  • 一样调用
  • 在刚刚添加的新键下,添加一个新的REG_SZ(字符串)值, 并将其称为 DllSurrogate。将值留空

  • 在HKey_Local_Machine\Software\Classes\AppID下创建一个新密钥\ 同样,新键的名称应与 COM 对象的 GUID 相同。 无需在此键下添加任何值。

就是这样,您的 COM 对象现在应该可以从 64 位环境访问,并且可以像普通 COM 对象一样使用。