├── .gitignore ├── README.md ├── RunScriptDemo.cpp ├── RunScriptDemo.vcxproj ├── SimpleScriptSite.cpp ├── SimpleScriptSite.h ├── pch.cpp └── pch.h /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | Debug 3 | *.user 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RunScriptDemo 2 | 3 | I've put together a "Hello World" IActiveScript C++ ATL console application that: 4 | 5 | - Define CSimpleScriptSite class 6 | - Implement IActiveScriptSite interface (mandatory) 7 | - Implement IActiveScriptSiteWindow interface (optional) 8 | - Minimum implementation with most functions implemented with a dummy stub 9 | - Has no error handling. Consult MSDN IActiveScriptError. 10 | - Use CoCreateInstance a new IActiveSite object 11 | - Create instances of both VBScript and JScript 12 | - Link the IActiveSite to IActiveScriptSite using IActiveSite::SetScriptSite 13 | - Call QueryInterface to get an IActiveScriptParse interface 14 | - Use IActiveScriptParse to execute VBScript or JScript code 15 | - The sample: 16 | - Evaluates an expression in JScript 17 | - Evaluates an expression in VBScript 18 | - Runs a command in VBScript 19 | 20 | References: 21 | - https://stackoverflow.com/a/9150038/881441 22 | - https://stackoverflow.com/questions/7491868/how-to-load-call-a-vbscript-function-from-within-c/9150038#9150038 23 | -------------------------------------------------------------------------------- /RunScriptDemo.cpp: -------------------------------------------------------------------------------- 1 | // RunScriptDemo.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | #include "SimpleScriptSite.h" 6 | #include 7 | #include 8 | 9 | void testExpression(const wchar_t* prefix, IActiveScriptParse* pScriptParse, LPCOLESTR script) 10 | { 11 | wprintf(L"%s: %s: ", prefix, script); 12 | HRESULT hr = S_OK; 13 | CComVariant result; 14 | EXCEPINFO ei = { }; 15 | hr = pScriptParse->ParseScriptText(script, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei); 16 | CComVariant resultBSTR; 17 | VariantChangeType(&resultBSTR, &result, 0, VT_BSTR); 18 | wprintf(L"%s\n", V_BSTR(&resultBSTR)); 19 | } 20 | 21 | void testScript(const wchar_t* prefix, IActiveScriptParse* pScriptParse, LPCOLESTR script) 22 | { 23 | wprintf(L"%s: %s\n", prefix, script); 24 | HRESULT hr = S_OK; 25 | CComVariant result; 26 | EXCEPINFO ei = { }; 27 | hr = pScriptParse->ParseScriptText(script, NULL, NULL, NULL, 0, 0, 0, &result, &ei); 28 | } 29 | 30 | int _tmain(int argc, _TCHAR* argv[]) 31 | { 32 | HRESULT hr = S_OK; 33 | hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 34 | 35 | // Initialize 36 | CSimpleScriptSite* pScriptSite = new CSimpleScriptSite(); 37 | CComPtr spJScript; 38 | CComPtr spJScriptParse; 39 | hr = spJScript.CoCreateInstance(OLESTR("JScript")); 40 | hr = spJScript->SetScriptSite(pScriptSite); 41 | hr = spJScript->QueryInterface(&spJScriptParse); 42 | hr = spJScriptParse->InitNew(); 43 | CComPtr spVBScript; 44 | CComPtr spVBScriptParse; 45 | hr = spVBScript.CoCreateInstance(OLESTR("VBScript")); 46 | hr = spVBScript->SetScriptSite(pScriptSite); 47 | hr = spVBScript->QueryInterface(&spVBScriptParse); 48 | hr = spVBScriptParse->InitNew(); 49 | 50 | // Run some scripts 51 | testExpression(L"JScript", spJScriptParse, OLESTR("(new Date).getTime()")); 52 | testExpression(L"VBScript", spVBScriptParse, OLESTR("Now")); 53 | testScript(L"VBScript", spVBScriptParse, OLESTR("MsgBox \"Hello World! The current time is: \" & Now")); 54 | // Outputs: 55 | // JScript: (new Date).getTime() : 1554685325378 56 | // VScript: Now : 8 / 04 / 2019 11 : 02 : 05 AM 57 | // VBScript: MsgBox "Hello World! The current time is: " & Now 58 | 59 | // Cleanup 60 | spVBScriptParse = NULL; 61 | spVBScript = NULL; 62 | spJScriptParse = NULL; 63 | spJScript = NULL; 64 | pScriptSite->Release(); 65 | pScriptSite = NULL; 66 | 67 | ::CoUninitialize(); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /RunScriptDemo.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {BE627107-FED3-49B4-8FC6-8FB8D25ADF24} 24 | Win32Proj 25 | RunScriptDemo 26 | 10.0.17763.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | true 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | pch.h 94 | 95 | 96 | Console 97 | true 98 | 99 | 100 | 101 | 102 | Use 103 | Level3 104 | Disabled 105 | true 106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 107 | true 108 | pch.h 109 | 110 | 111 | Console 112 | true 113 | 114 | 115 | 116 | 117 | Use 118 | Level3 119 | MaxSpeed 120 | true 121 | true 122 | true 123 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 124 | true 125 | pch.h 126 | 127 | 128 | Console 129 | true 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | Use 137 | Level3 138 | MaxSpeed 139 | true 140 | true 141 | true 142 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | pch.h 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Create 160 | Create 161 | Create 162 | Create 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /SimpleScriptSite.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "SimpleScriptSite.h" 3 | 4 | STDMETHODIMP_(ULONG) CSimpleScriptSite::AddRef() 5 | { 6 | return InterlockedIncrement(&m_cRefCount); 7 | } 8 | 9 | STDMETHODIMP_(ULONG) CSimpleScriptSite::Release() 10 | { 11 | if (!InterlockedDecrement(&m_cRefCount)) 12 | { 13 | delete this; 14 | return 0; 15 | } 16 | return m_cRefCount; 17 | } 18 | 19 | STDMETHODIMP CSimpleScriptSite::QueryInterface(REFIID riid, void **ppvObject) 20 | { 21 | if (riid == IID_IUnknown || riid == IID_IActiveScriptSiteWindow) 22 | { 23 | *ppvObject = (IActiveScriptSiteWindow *)this; 24 | AddRef(); 25 | return NOERROR; 26 | } 27 | if (riid == IID_IActiveScriptSite) 28 | { 29 | *ppvObject = (IActiveScriptSite *)this; 30 | AddRef(); 31 | return NOERROR; 32 | } 33 | return E_NOINTERFACE; 34 | } 35 | -------------------------------------------------------------------------------- /SimpleScriptSite.h: -------------------------------------------------------------------------------- 1 | #ifndef CSimpleScriptSite_H 2 | #define CSimpleScriptSite_H 3 | 4 | class CSimpleScriptSite : 5 | public IActiveScriptSite, 6 | public IActiveScriptSiteWindow 7 | { 8 | public: 9 | CSimpleScriptSite() : m_cRefCount(1), m_hWnd(NULL) { } 10 | 11 | // IUnknown 12 | 13 | STDMETHOD_(ULONG, AddRef)(); 14 | STDMETHOD_(ULONG, Release)(); 15 | STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); 16 | 17 | // IActiveScriptSite 18 | 19 | STDMETHOD(GetLCID)(LCID *plcid) { *plcid = 0; return S_OK; } 20 | STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) { return TYPE_E_ELEMENTNOTFOUND; } 21 | STDMETHOD(GetDocVersionString)(BSTR *pbstrVersion) { *pbstrVersion = SysAllocString(L"1.0"); return S_OK; } 22 | STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) { return S_OK; } 23 | STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) { return S_OK; } 24 | STDMETHOD(OnScriptError)(IActiveScriptError *pIActiveScriptError) { return S_OK; } 25 | STDMETHOD(OnEnterScript)(void) { return S_OK; } 26 | STDMETHOD(OnLeaveScript)(void) { return S_OK; } 27 | 28 | // IActiveScriptSiteWindow 29 | 30 | STDMETHOD(GetWindow)(HWND *phWnd) { *phWnd = m_hWnd; return S_OK; } 31 | STDMETHOD(EnableModeless)(BOOL fEnable) { return S_OK; } 32 | 33 | // Miscellaneous 34 | 35 | HRESULT SetWindow(HWND hWnd) { m_hWnd = hWnd; return S_OK; } 36 | 37 | public: 38 | LONG m_cRefCount; 39 | HWND m_hWnd; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed 2 | 3 | #include "pch.h" 4 | 5 | // In general, ignore this file, but keep it around if you are using pre-compiled headers. 6 | -------------------------------------------------------------------------------- /pch.h: -------------------------------------------------------------------------------- 1 | // Tips for Getting Started: 2 | // 1. Use the Solution Explorer window to add/manage files 3 | // 2. Use the Team Explorer window to connect to source control 4 | // 3. Use the Output window to see build output and other messages 5 | // 4. Use the Error List window to view errors 6 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 | 9 | #ifndef PCH_H 10 | #define PCH_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #endif //PCH_H 17 | --------------------------------------------------------------------------------