gpt4 book ai didi

c++ - 如何从 C++ 中加载和调用 VBScript 函数?

转载 作者:可可西里 更新时间:2023-11-01 13:03:40 34 4
gpt4 key购买 nike

我们有客户要求在我们的产品中发生特定操作时调用 VBScript 函数。我一直在努力研究 Windows 脚本技术,但我很难找到我需要的东西。希望你们中的一些人能提供帮助。

我们的产品是原生 C++ Windows 产品。客户会指定一个 VBScript 文件,我们会加载该文件,每当发生特定事件时,我们都会调用 VBScript 中的特定函数并让它执行它的操作。我们可能会在脚本的命名空间内提供对象,以便它也可以访问有关我们产品的信息。

我在 MSDN 上找到了一些关于 IActiveScript 接口(interface)和一些相关内容的信息,但找不到任何实例化为 VBScript 实现此接口(interface)的 COM 对象的示例。

我知道现在 PowerShell 可能是更好的选择,但我们的客户受困于许多遗留系统,而 VBScript 是他们所知道的。

如果您能提供任何帮助(链接或其他方式),我们将不胜感激!

最佳答案

我整理了一个“Hello World”IActiveScript C++ ATL 控制台应用程序:

  • 定义CSimpleScriptSite
    • 实现IActiveScriptSite接口(interface)(强制)
    • 实现IActiveScriptSiteWindow接口(interface)(可选)
    • 使用虚拟 stub 实现的大多数功能的最小实现
    • 没有错误处理。咨询MSDN IActiveScriptError .
  • 使用 CoCreateInstance 一个新的 IActiveSite 对象
    • 创建 VBScriptJScript 的实例>
    • 使用 IActiveSite::SetScriptSiteIActiveSite 链接到 IActiveScriptSite
    • 调用QueryInterface获取IActiveScriptParse接口(interface)
    • 使用IActiveScriptParse执行VBScriptJScript代码
  • 样本:
    • 计算 JScript 中的表达式
    • 计算 VBScript 中的表达式
    • VBScript 中运行命令

代码:

#include "stdafx.h"
#include <atlbase.h>
#include <activscp.h>

class CSimpleScriptSite :
public IActiveScriptSite,
public IActiveScriptSiteWindow
{
public:
CSimpleScriptSite() : m_cRefCount(1), m_hWnd(NULL) { }

// IUnknown

STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);

// IActiveScriptSite

STDMETHOD(GetLCID)(LCID *plcid){ *plcid = 0; return S_OK; }
STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) { return TYPE_E_ELEMENTNOTFOUND; }
STDMETHOD(GetDocVersionString)(BSTR *pbstrVersion) { *pbstrVersion = SysAllocString(L"1.0"); return S_OK; }
STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) { return S_OK; }
STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) { return S_OK; }
STDMETHOD(OnScriptError)(IActiveScriptError *pIActiveScriptError) { return S_OK; }
STDMETHOD(OnEnterScript)(void) { return S_OK; }
STDMETHOD(OnLeaveScript)(void) { return S_OK; }

// IActiveScriptSiteWindow

STDMETHOD(GetWindow)(HWND *phWnd) { *phWnd = m_hWnd; return S_OK; }
STDMETHOD(EnableModeless)(BOOL fEnable) { return S_OK; }

// Miscellaneous

HRESULT SetWindow(HWND hWnd) { m_hWnd = hWnd; return S_OK; }

public:
LONG m_cRefCount;
HWND m_hWnd;
};

STDMETHODIMP_(ULONG) CSimpleScriptSite::AddRef()
{
return InterlockedIncrement(&m_cRefCount);
}

STDMETHODIMP_(ULONG) CSimpleScriptSite::Release()
{
if (!InterlockedDecrement(&m_cRefCount))
{
delete this;
return 0;
}
return m_cRefCount;
}

STDMETHODIMP CSimpleScriptSite::QueryInterface(REFIID riid, void **ppvObject)
{
if (riid == IID_IUnknown || riid == IID_IActiveScriptSiteWindow)
{
*ppvObject = (IActiveScriptSiteWindow *) this;
AddRef();
return NOERROR;
}
if (riid == IID_IActiveScriptSite)
{
*ppvObject = (IActiveScriptSite *) this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}

int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

// Initialize
CSimpleScriptSite* pScriptSite = new CSimpleScriptSite();
CComPtr<IActiveScript> spJScript;
CComPtr<IActiveScriptParse> spJScriptParse;
hr = spJScript.CoCreateInstance(OLESTR("JScript"));
hr = spJScript->SetScriptSite(pScriptSite);
hr = spJScript->QueryInterface(&spJScriptParse);
hr = spJScriptParse->InitNew();
CComPtr<IActiveScript> spVBScript;
CComPtr<IActiveScriptParse> spVBScriptParse;
hr = spVBScript.CoCreateInstance(OLESTR("VBScript"));
hr = spVBScript->SetScriptSite(pScriptSite);
hr = spVBScript->QueryInterface(&spVBScriptParse);
hr = spVBScriptParse->InitNew();

// Run some scripts
CComVariant result;
EXCEPINFO ei = { };
hr = spJScriptParse->ParseScriptText(OLESTR("(new Date()).getTime()"), NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei);
hr = spVBScriptParse->ParseScriptText(OLESTR("Now"), NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei);
hr = spVBScriptParse->ParseScriptText(OLESTR("MsgBox \"Hello World! The current time is: \" & Now"), NULL, NULL, NULL, 0, 0, 0, &result, &ei);

// Cleanup
spVBScriptParse = NULL;
spVBScript = NULL;
spJScriptParse = NULL;
spJScript = NULL;
pScriptSite->Release();
pScriptSite = NULL;

::CoUninitialize();
return 0;
}

上面代码的一个版本可以在这里找到:

关于c++ - 如何从 C++ 中加载和调用 VBScript 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7491868/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com