0

我正在尝试从 C++ ATL 控制台应用程序(非 VBS 文件,而只是嵌入在我的代码中的脚本)执行 VBScript 并从中取回字符串。

我试过这样的事情:

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;

另请参阅此问题以了解如何设置:

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

如果我运行它,VBScript 会抱怨不存在的“WScript”对象。

我尝试替换WScript.EchoMsgBox并且代码工作正常(但当然不会返回字符串)。

我试着用这个:

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 之间共享一个。

4

1 回答 1

0

只需添加第二个调用,即可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;
于 2019-03-08T08:37:37.650 回答