【问题标题】:Is it possible to pipe a script to WScript?是否可以将脚本通过管道传输到 WScript?
【发布时间】:2016-04-06 06:59:51
【问题描述】:

我想执行我的应用程序使用 Windows 脚本宿主(wscript.exe 或 cscript.exe)生成的简单 VBScript/JScript,而不生成临时脚本文件。

我没有找到从标准输入流中读取脚本的命令行选项,但我确实在 WWW 中找到了几个记录 WScript 错误消息“无法从标准输入读取脚本”的位置。

MSDN Windows Script Host Reference - Error Messages

那么有隐藏的命令行选项可以从标准输入中读取脚本吗?

目前我的程序会生成一个小脚本并将其写入临时文件。然后它创建一个运行cscript.exe 的子进程,等待它完成,然后再次删除临时文件。如果可能的话,我想摆脱临时文件并将脚本直接传递给脚本主机。 (例如,将其传递给cscript.exe 或将其作为类似于cmd.exe 的/c 命令行选项的命令行参数的一部分传递)

【问题讨论】:

  • 你能发一个例子吗?从什么生成vbscript?请多解释!
  • 您可以在当前进程中执行您的代码字符串,还是需要在新进程中运行?
  • @AlexK。你能详细说明吗?我很感兴趣,你如何在没有临时文件的情况下将动态脚本传递给cscript.exe 进程。
  • 我的意思是,如果代码不需要在单独的进程中运行,他可以通过 .Execute 或 ScriptControl 在当前进程中运行他的字符串

标签: windows stdin wsh


【解决方案1】:

不幸的是,简短的回答是不。 WScript 引擎不提供通过管道或命令参数传递脚本的方法,唯一的选择是使用StdIn 来解释和处理命令(在下面展开)


使用StdIn 从命令行直接解释和执行代码

不确定自己,但想测试一下...

值得注意的是,下面的测试仍然需要一个脚本来解释输入,这可能不符合要求,但太通用了,我不会将其归类为临时脚本。

我可以看到的问题是,您想要传递的代码越复杂,就越难通过管道传递给cscript.exe 程序。

这是一个简单的示例,它只是将 MsgBox() 调用通过管道传递给 cscript.exe

命令行:

echo MsgBox("test piping") | cscript.exe /nologo "test.vbs"

test.vbs的内容

Dim stdin: Set stdin = WScript.StdIn
Dim line: line = stdin.ReadAll

Call ExecuteGlobal(line)

在命令行上处理多行

echo 管道传输多行并不容易,如果在传入后使用字符作为分隔符来分解命令,它可能会更好。例如;

echo MsgBox("test piping")^^^^Msgbox("test Complete") | cscript.exe /nologo "test.vbs"

然后使用

Split(stdin.ReadAll, "^")

分解要执行的命令行。


这是一个更复杂的例子;

命令行:

echo Dim i: i = 1^^^^i = i + 2^^^^MsgBox("i = " ^^^& i) | cscript /nologo "test.vbs"

test.vbs的内容:

Dim line Dim stdin: Set stdin = WScript.StdIn

For Each line In Split(stdin.ReadAll, "^")   
  'Takes each line from StdIn and executes it.
  Call ExecuteGlobal(line)
Next

使用^ 作为分隔符为我自己的背做了一根棍子,因为这在命令行中具有特殊含义并且需要转义(恰好是^),加上事实它必须在管道时再次转义,因此^^^^

意识到分解行并单独执行它们可能会导致更多问题(例如,Function 定义会失败)。这让我重新思考了这个方法,发现它应该更简单。

Dim stdin: Set stdin = WScript.StdIn
Dim input: input = Replace(stdin.ReadAll, "^", vbCrLf)

Call ExecuteGlobal(input)

【讨论】:

  • 感谢您的回答。但这不是我的问题的解决方案,因为我仍然需要生成 test.vbs。我正在寻找一个没有临时文件的解决方案,即根本没有持久化的脚本文件。
  • @niks 那么答案是否定的。虽然您可以将其归类为临时文件,但它完全独立于您从命令行传入的任何动态代码,并且它是您将获得的最接近解决方案的解决方案。
  • @niks 我已经更新了答案,抱歉,我无法提供更多帮助。
  • 再次感谢您的回答。我接受了。无论如何,“不”是我所期望的答案。由于链接的 MSDN 错误消息文档,我只是想知道我是否遗漏了什么。
  • 非常好!根据您的回答使用单行:ExecuteGlobal WScript.StdIn.ReadAll。分行可以批量进行:(ECHO WScript.Echo "Line 1"&ECHO WScript.Echo "Line 2")|CSCRIPT //NOLOGO EXEC.VBS
【解决方案2】:

我正在寻找一种将脚本传送到 wscript(实际上是 cscript)的方法,以便在 Windows 服务关闭期间执行可能长时间运行的任务,并且不想等待它完成以删除临时脚本文件。我决定让脚本在完成后删除文件本身:

' do work
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName

Set objFSO = CreateObject("Scripting.FileSystemObject") 
objFSO.DeleteFile(strPath) 

【讨论】:

    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 2018-07-30
    • 2017-01-15
    相关资源
    最近更新 更多