是否可以将脚本通过管道传输到 WScript?
Is it possible to pipe a script to WScript?
我想执行由我的应用程序使用 Windows 脚本宿主(wscript.exe 或 cscript.exe)生成的简单 VBScript/JScript,而不生成临时脚本文件。
我没有找到从标准输入流读取脚本的命令行选项,但我确实在 WWW 中找到了几个记录 WScript 错误消息的地方 "Can't read script from stdin."
MSDN Windows Script Host Reference - Error Messages
那么是否有一个隐藏的命令行选项可以从标准输入中读取脚本?
目前我的程序生成一个小脚本并将其写入一个临时文件。然后它创建一个子进程运行 cscript.exe
,等待它完成然后再次删除临时文件。如果可能的话,我想摆脱临时文件并将脚本直接传递给脚本宿主。 (例如,将其通过管道传递给 cscript.exe
或将其作为命令行参数的一部分传递,类似于 cmd.exe
的 /c 命令行选项)
很遗憾,简短的回答是否定的。 WScript 引擎不提供通过管道或通过命令参数传递脚本的方法,唯一的选择是使用 StdIn
来解释和处理命令 (在下面展开).
使用StdIn
直接从命令行解释和执行代码
我自己不确定,但想测试一下...
Worth noting that the testing below still requires a script to interpret the input which is probably not going to fit the requirement but is so generic I wouldn't class it as a temporary script.
我看到的问题是,您要传递的代码越复杂,就越难通过管道传递给 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)
我正在寻找一种方法将脚本通过管道传输到 wscript(实际上是 cscript),以便在 Windows 服务关闭期间执行可能很长的 运行 任务,并且不想等待它完成以删除临时脚本文件。我决定让脚本在完成后删除文件本身:
' do work
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile(strPath)
我想执行由我的应用程序使用 Windows 脚本宿主(wscript.exe 或 cscript.exe)生成的简单 VBScript/JScript,而不生成临时脚本文件。
我没有找到从标准输入流读取脚本的命令行选项,但我确实在 WWW 中找到了几个记录 WScript 错误消息的地方 "Can't read script from stdin."
MSDN Windows Script Host Reference - Error Messages
那么是否有一个隐藏的命令行选项可以从标准输入中读取脚本?
目前我的程序生成一个小脚本并将其写入一个临时文件。然后它创建一个子进程运行 cscript.exe
,等待它完成然后再次删除临时文件。如果可能的话,我想摆脱临时文件并将脚本直接传递给脚本宿主。 (例如,将其通过管道传递给 cscript.exe
或将其作为命令行参数的一部分传递,类似于 cmd.exe
的 /c 命令行选项)
很遗憾,简短的回答是否定的。 WScript 引擎不提供通过管道或通过命令参数传递脚本的方法,唯一的选择是使用 StdIn
来解释和处理命令 (在下面展开).
使用StdIn
直接从命令行解释和执行代码
我自己不确定,但想测试一下...
Worth noting that the testing below still requires a script to interpret the input which is probably not going to fit the requirement but is so generic I wouldn't class it as a temporary script.
我看到的问题是,您要传递的代码越复杂,就越难通过管道传递给 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)
我正在寻找一种方法将脚本通过管道传输到 wscript(实际上是 cscript),以便在 Windows 服务关闭期间执行可能很长的 运行 任务,并且不想等待它完成以删除临时脚本文件。我决定让脚本在完成后删除文件本身:
' do work
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile(strPath)