How to load and call a VBScript function from C ++?

We have clients that require VBScript functions to be called when certain actions occur in our product. I tried to research Windows Scripting technologies, but itโ€™s hard for me to find what I need. Hope some of you can help.

Our product is a native Windows C ++ product. The client will specify the VBScript file that we will load, and whenever a specific event occurs, we call a specific function in VBScript and let it do it. We can provide objects in the script namespace to access information about our product.

I found some information about MSDN about the IActiveScript interface and some related things, but I can not find examples of creating an instance of a COM object that implements this interface for VBScript.

I know that PowerShell will probably be the best option for this these days, but our clients are stuck in many legacy systems, and VBScript is what they know.

Any help you can provide (links or others) will be appreciated!

+7
source share
3 answers

Take a look at this for some sample code http://support.microsoft.com/kb/221992

There is msscript.ocx that can help you, but probably more problems than its value if you can write C ++ http://msdn.microsoft.com/en-us/magazine/cc302278.aspx

+2
source

I compiled the IActiveScript C ++ ATL "Hello World" console application, which:

  • Define CSimpleScriptSite Class
    • Implement IActiveScriptSite interface (required)
    • IActiveScriptSiteWindow interface (optional)
    • Minimal implementation with most functions implemented with stub
    • It has no error handling. See MSDN IActiveScriptError .
  • Use CoCreateInstance new IActiveSite
    • Create instances of both VBScript and JScript
    • Associate IActiveSite with IActiveScriptSite using IActiveSite::SetScriptSite
    • Call QueryInterface to get the IActiveScriptParse interface
    • Use IActiveScriptParse to execute VBScript or JScript code
  • Example:
    • Evaluates Expression in JScript
    • Evaluates Expression in VBScript
    • Runs a command in VBScript

The code:

 #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; } 

A version of the above code can be found here:

+12
source

IActiveScript and related interfaces work very well. I use them in my product exactly as you described. Some of the clients write their own VBScript and JScript scripts to analyze and update the application data before they are sent to the database.

You use CoCreateInstance() to instantiate an IActiveScript , like any other COM object. Then you call its QueryInterface() method to get the IActiveScriptParse interface to load the script code snippets, and then you update the IActiveScript state to execute the code.

You can add custom objects to the script by implementing IDispatch defined classes and then passing them to the engine using IActiveScript::AddNamedItem() and the IActiveScript::AddNamedItem() callback.

There are examples of using IActiveScript .

+2
source

Source: https://habr.com/ru/post/897712/


All Articles