我正在使用 Zbarimg,我相信它会将数据输出到 STDOUT。因此,目前,VBScript 中的 cmd 字符串执行命令并将其存储在变量中,因此:
xml_data=objShell.Exec("C:\MobiEvent\Zbar\bin\zbarimg -D -q --xml C:\MobiEvent\AllPics\*.jpg").stdout.readall
(对于初学者来说,-D 会停止显示从图像中读取的条形码的图像,而 -q 会保持安静,因此只输出 XML 数据)如果 AllPics 的所有数据都存储在 xml_data 中,那么一切都会顺利进行。问题是,像往常一样,控制台会弹出一个窗口,该窗口在脚本处理期间保持打开状态。如果有 200 多张照片,它会保持打开状态一段时间
另一种方法是使用 Run 命令,并在末尾标记“,0,False”...但当然,StdOut 输出不会被选择进行后期处理!
我想知道是否可以使用管道将两者结合起来,我的理论语法是......
objShell.Run("C:\MobiEvent\Zbar\bin\zbarimg -D -q --xml C:\MobiEvent\AllPics\*.jpg"|to other script),0,True
** 甚至不确定程序是否会这样做,因为它可能会将管道读取为目录路径的一部分
这又引出了下一个问题。如果可以将 STDOUT 输出到管道中,我该如何将该管道输出读回到第二个 VBScript 程序中?(我需要做的就是将程序的输出打印到文件中,以便我可以再次读取并将其拆分成组成部分来进行后期处理,从而得出照片文件名和 QR 值)
我知道“Run=隐藏窗口 / Exec=无法隐藏”的争论已经持续了一段时间。我只是想知道上述方法是否可能成为一种替代选择。
答案1
这个答案晚了 6 年,但是 VBScript 可以执行命令并存储输出,而无需依赖管道或将输出写入临时文件。
此函数执行一条命令(不显示控制台窗口)并将输出作为数组返回:
Function Execute_Command(sCmd)
Dim i : i = 0
Dim oExec : Set oExec = CreateObject("WScript.Shell").Exec(sCmd)
Do Until oExec.StdOut.AtEndOfStream
ReDim Preserve sOutput(i)
sOutput(i) = oExec.StdOut.ReadLine()
i = i + 1
Loop
Set oExec = Nothing
' If no output produced, create an empty array
If i = 0 Then Redim sOutput(0)
Execute_Command = sOutput
End Function
两点说明:
- 虽然您可以将每一行连接成一个字符串然后返回它,但您会发现处理大量输出会对性能产生很大影响(大约慢 10 倍!)
- 虽然如果没有输出就不需要创建一个空数组,但确保函数始终返回一个数组可以使生活变得更轻松。
要使用,请尝试以下操作:
Dim sLine
For Each sLine In Execute_Command("ping -n 2 superuser.com")
WScript.Echo "=> " & sLine
Next
生成以下输出:
C:\Users\Richard\Desktop>cscript /nologo exec.vbs
=>
=> Pinging superuser.com [151.101.65.69] with 32 bytes of data:
=> Reply from 151.101.65.69: bytes=32 time=12ms TTL=60
=> Reply from 151.101.65.69: bytes=32 time=13ms TTL=60
=>
=> Ping statistics for 151.101.65.69:
=> Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
=> Approximate round trip times in milli-seconds:
=> Minimum = 12ms, Maximum = 13ms, Average = 12ms
答案2
我不知道您的具体软件是什么,但您可以使用 .Run 命令在 vbScript 中进行管道传输和重定向。例如:
' demonstrate piping and redirecting output with .Run
Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTemp=objShell.ExpandEnvironmentStrings("%TEMP%") & "\"
strCmd=objShell.ExpandEnvironmentStrings("%comspec%") & " /C"
' here is the action
objShell.Run strCmd & "echo hello and welcome|findstr /N welcome >" & strTemp & "test.txt",0, True
' read the file back to show it was created successfully
Set file = objFSO.OpenTextFile(strTemp & "test.txt", 1)
strTaskText = file.ReadAll
strTaskText=Left(strTaskText,Len(strTaskText)-2) ' remove trailing vbCrLf
file.Close
MsgBox "The output was:" & vbcrlf & strTaskText