我正在尝试运行Shell命令进行Google语音识别。如果我将输出文件提供给命令字符串,则只能运行命令 。
您可以在下面看到我的测试代码示例,如果提供了该代码,我将附加“> outputFile ”,并在超时循环中进行编码,以在设置的时间限制后中止该过程。
strCommand = "cmd /c ipconfig /all"
If outputFile <> "" Then
strCommand = strCommand & " > """ & outputFile & """"
End If
Set wshShellExec = wshShell.Exec(strCommand)
expiration = DateAdd("s", 600, Now)
Do While wshShellExec.Status = WshRunning And Now < expiration
WScript.Sleep 5000
Loop
Select Case wshShellExec.Status
Case WshRunning
wshShellExec.Terminate
TestFunction = "{""error"": ""TestFunction Command Timed Out""}"
Case WshFinished
TestFunction = WshShellExec.StdOut.ReadAll()
Case WshFailed
TestFunction = wshShellExec.StdErr.ReadAll()
End Select
如果我将outputFile
保留为空,并希望从该函数返回输出,则它所要做的只是静止5分钟,然后超时并向我发送错误消息。
为什么需要输出文件才能运行?
如果我在命令提示符上手动运行命令行,它将运行得很好。
答案 0 :(得分:0)
一旦wshShellExec
在WshRunning
情况下终止,则应该分配输出,而不是分配错误消息。
Select Case wshShellExec.Status
Case WshRunning
wshShellExec.Terminate
TestFunction = "Terminated: " & vbcrlf & WshShellExec.StdOut.ReadAll()
Case WshFinished
TestFunction = "Finished: " & vbcrlf & WshShellExec.StdOut.ReadAll()
Case WshFailed
TestFunction = wshShellExec.StdErr.ReadAll()
End Select
答案 1 :(得分:0)
输出缓冲区的容量有限。如果您的命令写了太多文本无法输出,缓冲区将填满并阻止该命令继续写命令,直到您清除缓冲区为止(例如,通过读取缓冲区)。 ReadAll
不能用于此目的,因为该方法仅在命令完成后返回 ,否则将阻塞,从而造成死锁。
您最好的选择是将输出重定向到一个或多个(临时)文件,并在命令完成后从这些文件中读取输出。
outfile = "C:\out.txt"
errfile = "C:\err.txt"
cmd = "cmd /c ipconfig /all >""" & outfile & """ 2>""" & errfile & """"
timeout = DateAdd("s", 600, Now)
Set sh = CreateObject("WScript.Shell")
Set ex = sh.Exec(cmd)
Do While ex.Status = WshRunning And Now < timeout
WScript.Sleep 200
Loop
Set fso = CreateObject("Scripting.FileSystemObject")
outtxt = fso.OpenTextFile(outfile).ReadAll
errtxt = fso.OpenTextFile(errfile).ReadAll
如果由于某些原因您不想这样做,则必须反复阅读StdOut
。
outtxt = ""
errtxt = ""
cmd = "ipconfig /all"
timeout = DateAdd("s", 600, Now)
Set sh = CreateObject("WScript.Shell")
Set ex = sh.Exec(cmd)
Do While ex.Status = WshRunning And Now < timeout
WScript.Sleep 200
outtxt = outtxt & ex.StdOut.ReadLine & vbNewLine
Loop
请注意,您可能还需要从StdErr
中读取内容,因为如果错误输出过多,该缓冲区也可能会填满。但是,读取两个缓冲区都可能导致另一个死锁,因为IIRC ReadLine
会阻塞直到可以读取整行为止,因此如果脚本可能挂起以等待错误输出永远不会出现。您也许可以使用Read
而不是ReadLine
来解决此问题,但它仍然非常脆弱。
因此,再次,您最好的选择是将命令输出重定向到文件,并在命令终止后读取这些文件。