我在将 c++ 应用程序从 32 位移植到 64 位时遇到了同样的问题。我知道这个问题是在 Delphi 上提出的,但我希望有人可以利用这些信息或将其转移到其他语言。
我们通过 CreateDispatch 启动“ScriptControl”(MSScriptControl.ScriptControl.1)。控制信息位于 Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ScriptControl 中,我们使用 32 位的这个 MS 控制执行 VBS 或 JScript:
COleDispatchDriver* m_dispScriptControl = new COleDispatchDriver();
if (m_dispScriptControl)
{
if (m_dispScriptControl->CreateDispatch(_T("ScriptControl")))
{
...
.... setting language to be used and other proteries .. then execute script code:
_variant_t varResult;
VariantClear(&varResult);
EXCEPINFO excepinfo;
VARIANT parameters;
parameters.vt = VT_BSTR;
parameters.bstrVal = strScriptCodeWCHAR;
DISPPARAMS dispparams;
dispparams.rgdispidNamedArgs = NULL;
dispparams.cNamedArgs = 0;
dispparams.cArgs = 1;
dispparams.rgvarg = ¶meters;
unsigned int uArgErr = 0;
if (S_OK != m_dispScriptControl->m_lpDispatch->Invoke(0x7d2, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, &excepinfo, &uArgErr))
...
}
经过一些研究,似乎不可能在 64 位应用程序中创建 ScriptControl 作为 MSDN 查询:
问题是:我的窗体应用程序目前在 32 位应用程序上运行良好,我正在调查,因此我们可以将其安装在 64 位计算机上,但继续启动应用程序,如下所示。
类未注册(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))
错误位于 AxInterop.MSScriptControl.dll
Awnser 是:如果它只存在于 C:\Windows\SysWOW64 中,那么您的 .Net 应用程序无法在 64 位模式下运行。确保为 x86 而不是 Any CPU 编译它。然后您将能够在 64 位 Windows 中使用它,但它将是一个 32 位进程。
https://social.msdn.microsoft.com/Forums/windows/en-US/1e9ddfe4-3408-4a34-ba43-a1a0931daebd/64-bit-windows-7?forum=clr
对此我们不满意,因为我们想以 64 位进程运行
我们的解决方案是使用 Microsoft IActiveScript 接口。并在我们的主窗口上实现了相同的功能:
BEGIN_INTERFACE_PART(ActiveScriptSite, IActiveScriptSite)
STDMETHOD(GetLCID)(LCID*);
STDMETHOD(GetItemInfo)(LPCOLESTR, DWORD, LPUNKNOWN*, LPTYPEINFO*);
STDMETHOD(GetDocVersionString)(BSTR*);
STDMETHOD(OnScriptTerminate)(const VARIANT*, const EXCEPINFO*);
STDMETHOD(OnStateChange)(SCRIPTSTATE);
STDMETHOD(OnScriptError)(IActiveScriptError*);
STDMETHOD(OnEnterScript)();
STDMETHOD(OnLeaveScript)();
END_INTERFACE_PART(ActiveScriptSite)
现在,当我们必须执行脚本代码时,我们执行以下操作,这在我们构建的 64 位和 32 位版本中运行良好:
CString strLanguage;
if (nLanguage == 1)
{
strLanguage = _T("VBScript");
}
else
{
strLanguage = _T("JScript");
}
CComPtr<IActiveScript> m_pAxsScript;
HRESULT hr = m_pAxsScript.CoCreateInstance(CT2W(strLanguage), NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER);
m_pAxsScript->SetScriptSite(&m_xActiveScriptSite); //m_xActiveScriptSite is a member of the interface
CComQIPtr<IActiveScriptParse> m_pAxsScriptParse = m_pAxsScript;
m_pAxsScriptParse->InitNew();
EXCEPINFO pException = { 0 };
hr = m_pAxsScriptParse->ParseScriptText(_bstr_t(strCode), 0, NULL, NULL, dw, 0, 0, NULL, &pException);
//execute script
m_pAxsScript->SetScriptState(SCRIPTSTATE_CONNECTED);
m_pAxsScriptParse.Release();
m_pAxsScriptParse = nullptr;
hr = m_pAxsScript->SetScriptState(SCRIPTSTATE_DISCONNECTED);
ASSERT(hr == S_OK);
m_pAxsScript->Close();
m_pAxsScript.Release();