VBA CreateObject 无法在 64 位 Windows 上创建 ActiveX 组件

Posted

技术标签:

【中文标题】VBA CreateObject 无法在 64 位 Windows 上创建 ActiveX 组件【英文标题】:VBA CreateObject can’t create ActiveX component on 64Bit Windows 【发布时间】:2018-01-31 17:16:36 【问题描述】:

我必须在 Visual Studio 2013 中编写一个程序,但它不起作用,因此我开始使用 Microsoft Excel 及其开发平台测试所有可能性。我从以下版本开始(由提供我需要使用的程序的公司提供):

Sub Main()

    Dim XServer As X2000.Server
    Dim XApp As X2000.Application
    Dim XSR As X2000.ScriptRoutines

    Set XServer = New X2000.Server
    Set XApp = XServer.AppConnection()    '<- This actually fires the application
    XApp.Visible = True

    Set XSR = XApp.ScriptCommands
    XSR.DATA_FILENAME = "C:\X2000\myFile.x"    ' <- Code blocks here

End Sub

这基本上启动了应用程序 X2000.exe,将我的代码连接到它,然后通过在程序中加载 myFile.x 来执行 DATA_FILENAME 分配例程。我需要启动应用程序,因为此时它的许可证已被检查,并且我没有任何其他选项可以使用。

现在,在这个版本中,代码在最后一行被阻塞,在没有任何其他信息的情况下说“A dll is missing”。我尝试通过执行以下操作来后期绑定 ScriptRoutines 对象:

Dim XServer As X2000.Server
Dim XApp As X2000.Application
Dim XSR As Object

Set XServer = New X2000.Server
Set XApp = XServer.AppConnection()
XApp.Visible = True

XSR = CreateObject("XApp.ScriptCommands")

这也不好用,但确实给了我更多信息:“ActiveX 控件无法加载对象”。我做了一些研究,通过“Dependancy Walker”发现X2000.exe 依赖于MSVBVM60.DLL,而system32 文件夹中缺少该MSVBVM60.DLL。不过很好奇,因为我的系统是 64 位的,Excel 也是,我在 VS2013 上尝试了使用 32 位兼容性的代码,但代码仍然不起作用。 我安装了the service pack from Microsoft,该文件所在的位置,却发现system32 未被触及... sysWoW64 已经有一个 MSVBVM60.DLL,因此我怀疑 X2000.exe 仅用于 32 位系统:我错了。

我的一位同事可以执行用 MATLAB 代码编写的相同程序:

function [Data,eng_or_met] = Read_X2000_File_BB_2(sFileName)

XServer = actxserver('X2000.server');
XApp = XServer.AppConnection;
XApp.Visible = 1;
objX2000 = XApp.ScriptCommands;
objX2000.data_filename = "C:\X2000\myFile.x";

delete(XServer);

感谢actxserver function,我相信这个代码可以解决这个兼容性问题。

如何使用 Excel/VS2013 做同样的事情?

编辑:

我尝试了 omegastripes 建议的代码:

Dim XSR As Object
Set XSR = CreateObjectx86("XApp.ScriptCommands") ' create ActiveX via x86 mshta host

CreateObjectx86 函数linked here。我尝试了If / Else 条件,最后无论如何都没有创建对象,两者都有:

Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID)

Set CreateObjectx86 = CreateObject(sProgID)

如果我不更改代码,最后一行将被执行(因此不是#If Win64)。

编辑:

根据这个问题的第一个答案,我也试过:

Dim XServer As Object
Dim XApp As X2000.Application
Dim XSR As X2000.Script

Set XServer = CreateObject("X2000.Server")
Set XApp = XServer.AppConnection()
XApp.Visible = True
Set XSR = X2000.ScriptCommands

只是发现我得到了同样的错误。

【问题讨论】:

可能 actxserver 正在做完全相同的事情,但上下文不同。如果您的应用程序是使用 VB6 编写的,那么您必须在某处拥有 MSVBVM60.dll。运行这个:microsoft.com/en-us/download/details.aspx?id=24417 也检查这个blogs.msdn.microsoft.com/deva/2009/12/30/… 如果您的应用是使用本地化版本的 VB6 构建的,请确保安装本地化的 VB6 支持二进制文件 我从 Microsoft 安装了包含此文件的服务包 X2000 是用本地化的 VB6 制作的,但我猜这是每个 VB6 附带的标准版本,因为提供X2000 的公司来自美国 如果它来自美国,我认为您确实不需要任何本地化的东西。我要做的是使用 sysinternal 的 procmon 工具并监视文件(按程序的 exe 名称过滤)。这可以帮助您确定丢失的内容。它可能是卫星文件,也可能是您没有想到的文件。 我不熟悉它,但我想我可以尝试...如果我只是一个管理员 -_- @Noldor130884 我猜您正在使用 64 位 Office 版本进行测试,而 MATLAB 是 32 位版本,而 ActiveX 仅适用于 32 位应用程序,因此它可以在 x64 操作系统上的 MATLAB 中通过魔兽世界64。您可以尝试使用this method 进行后期绑定。 【参考方案1】:

我显然解决了这个问题。受 Hans Passant 的启发,我将 Dimed XServer 作为唯一的对象,具体取决于对 X2000.exe 的引用:

Dim XServer As X2000.Server
Dim XApp As Object
Dim XSR As Object

Set XServer = New X2000.Server
Set XApp = XServer.AppConnection
XApp.Visible = True
Set XSR = XApp.ScriptCommands

XSR.DATA_FILENAME = "C:\foo.x" 

DATA_FILENAME 实际上是一个被执行的“ScriptCommand”。

就这么简单。但是我不知道为什么会这样。

【讨论】:

以上是关于VBA CreateObject 无法在 64 位 Windows 上创建 ActiveX 组件的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Windows 7 x64 上使用 VB 脚本中的 CreateObject

错误 429 excel vba activex CreateObject(“SAP.Functions”)

VBA研究64位系统下无法用ScriptControl控件解析JSon数据

vba createobject函数 报错

VBA 在 64 位 Excel 中打开屏幕键盘

VBA在32位下没问题,到64位异常报错