Как получить значение из VBScript для моего хоста C++?
Я пытаюсь выполнить VBScript из консольного приложения C++ ATL (не VBS-файл, а просто скрипт, встроенный в мой код) и получить из него строку.
Я попробовал что-то вроде этого:
HRESULT hr = S_OK;
CComVariant result;
EXCEPINFO ei = { };
LPCOLESTR sCmd = L"s = \"something\"\r\n"
"WScript.Echo s\r\n";
hr = spVBScriptParse->ParseScriptText(sCmd, NULL, NULL, NULL, 0, 0, 0, &result, &ei);
std::cout << "got:" << result.cVal << std::endl;
Смотрите также этот вопрос о том, как это настроить:
Как загрузить и вызвать функцию VBScript из C++?
Если я запускаю это, VBScript жалуется на несуществующий объект "WScript".
Я пытался заменить WScript.Echo
с MsgBox
и код работает нормально (но, конечно, не возвращает строку).
Я пытался использовать это:
LPCOLESTR sCmd = L"s = \"something\"\r\n"
"Set fso = CreateObject (\"Scripting.FileSystemObject\")\r\n"
"Set stdout = fso.GetStandardStream (1)\r\n"
"stdout.WriteLine s\r\n"
Это записывает мою строку в консоль, где было запущено приложение C++, но не возвращает строку обратно в мой код.
Как я могу получить значение s
из сценария в мой хост-процесс?
Просто чтобы уточнить: я не хочу сохранять VBS, а не строку во временный файл.
Цель состоит в том, чтобы сохранить все в памяти без доступа к диску.
Я знаю, что могу использовать реестр, но я бы хотел избежать повышения. Не знаю, доступно ли некоторое разделение памяти для vbscript.
Другой идеей были именованные каналы, но я понятия не имею, как разделить их между C++ и vbscript.
1 ответ
Просто добавьте второй звонок ParseScriptText
который оценивает вашу строковую переменную как выражение.
Вы должны пройти SCRIPTTEXT_ISEXPRESSION
как dwFlags
аргумент, так что механизм сценариев знает, что вы хотите получить значение выражения.
Это также в официальной документации для ParseScriptText:
https://docs.microsoft.com/en-us/scripting/winscript/reference/iactivescriptparse-parsescripttext
Я проверил его в Delphi, и он работает как шарм:
procedure TestActiveScripting;
const
SCRIPTTEXT_ISEXPRESSION = $00000020;
var
hr: HResult;
ScriptSite: IActiveScriptSite;
VBScript: IActiveScript;
VBScriptParse: IActiveScriptParse;
res: Variant;
ei: TExcepInfo;
begin
// Initialize
ScriptSite := TSimpleScriptSite.Create as IActiveScriptSite;
hr := CoCreateInstance(CLSID_VBScript, nil, CLSCTX_INPROC_SERVER, IID_IActiveScript, VBScript);
hr := VBScript.SetScriptSite(ScriptSite);
VBScriptParse := VBScript as IActiveScriptParse;
hr := VBScriptParse.InitNew;
// Run some scripts
hr := VBScriptParse.ParseScriptText('s = "something"', nil, nil, nil, 0, 0, 0, @res, ei);
hr := VBScriptParse.ParseScriptText('s', nil, nil, nil, 0, 0, SCRIPTTEXT_ISEXPRESSION, @res, ei);
ShowMessage(res);
end;