先上代码,照着代码直接调用是没有问题的
#ifdef _WIN64
#import "C:/Windows/System32/msscript.ocx" no_namespace
#ifdef _DEBUG
#include "x64/Debug/msscript.tlh"
#else
#include "x64/Release/msscript.tlh"
#endif
#else
#import "C:/Windows/SysWOW64/msscript.ocx" no_namespace
#ifdef _DEBUG
#include "Debug/msscript.tlh"
#else
#include "Release/msscript.tlh"
#endif
#endif
class Script
{
private:
HRESULT hr;
IScriptControlPtr pScriptControl;
public:
Script ():
hr(CoInitialize (NULL)),
pScriptControl(__uuidof(ScriptControl))
{
pScriptControl->put_Language ((BSTR)L"JavaScript");
pScriptControl->PutAllowUI (VARIANT_FALSE);
}
~Script ()
{
pScriptControl->Release ();
CoUninitialize ();
}
void AddCode (const wchar_t* pCodes)
{
BSTR strCodes = SysAllocString (pCodes);
if (!SUCCEEDED (pScriptControl->raw_AddCode (strCodes)))
{
const char* errstr = pScriptControl->GetError ()->GetText ();
if (errstr)
{
std::cout << errstr;
}
}
SysFreeString (strCodes);
}
void RunCode (const wchar_t* pCodes)
{
BSTR strCodes = SysAllocString(pCodes);
if (!SUCCEEDED (pScriptControl->raw_ExecuteStatement (strCodes)))
{
const char* pErrStr = pScriptControl->GetError ()->GetText ();
std::cout << pErrStr;
}
SysFreeString (strCodes);
}
void Call (const wchar_t* pFuncName, VARIANT& Result, long nParam = 0, ...)
{
LPSAFEARRAY pSafeArray = NULL;
LPVARIANT pVarChunk = NULL;
//1维数组参数
SAFEARRAYBOUND ArrBounds;
ArrBounds.cElements = nParam;
ArrBounds.lLbound = 0;
pSafeArray = SafeArrayCreate (VT_VARIANT, 1, &ArrBounds);
if (nParam)
{
pVarChunk = new VARIANT[nParam];
if (!pSafeArray || !pVarChunk)
{
throw "Alloc Failed";
}
va_list _ArgList;
va_start (_ArgList, nParam);
for (long i = 0; i < nParam; i++)
{
VariantInit (&pVarChunk[i]);
V_VT (&pVarChunk[i]) = VT_BSTR;
V_BSTR (&pVarChunk[i]) = SysAllocString (va_arg (_ArgList, const wchar_t*));
SafeArrayPutElement (pSafeArray, &i, &pVarChunk[i]);
}
va_end (_ArgList);
}
VariantInit (&Result);
BSTR strName = SysAllocString (pFuncName);
if (!SUCCEEDED (pScriptControl->raw_Run (strName, &pSafeArray, &Result)))
{
const char* errstr = pScriptControl->GetError ()->GetText ();
if (errstr)
{
std::cout << errstr;
}
}
SysFreeString (strName);
if (pSafeArray)
{
for (long i = 0; i < nParam; i++)
{
SysFreeString (V_BSTR (&pVarChunk[i]));
}
SafeArrayDestroy (pSafeArray);
}
}
};
下面说注意的点
OCX这个控件在我的系统里存在于C:/Windows/SysWOW64目录下, 是32位PE, 没有找到64位的版本
导入后会在中间目录生成.tlh文件, 相当于头文件, 如果我默认的路径不对自己修改下
调用接口时,注意它所有为BSTR的参数最好都用SysAllocString去创建, 用完记得释放