Это странный вопрос, основанный на плохом поведении VBScript, который я пытаюсь обойти.Пожалуйста, потерпите меня и спасибо заранее.
В VBScript вы можете сделать следующее, чтобы запустить задачу:
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
Do While WshShellExec.Status <> WshFinished
WScript.Sleep(1000)
Loop
Однако, есть ошибка, если, если команда /задача, запущенная вызовом WshShell.Exec, записывает> = 4kb в StdOut или StdErr, WshShellExec.Status никогда не будет равен WshFinished (1).Я предполагаю, что это связано с тем, что в буфере нет места, которое система использует для stdout / stderr, поэтому инициируемая задача зависает при следующей записи в stdout / stderr, как только записывает достаточно байтов в буфер (ы).
В зависимости от запущенной программы вы можете сделать что-то вроде следующего, чтобы обойти это:
Set wshShellExec = WshShell.Exec(cmd)
Set objStdOut = wshShellExec.StdOut
Set objStdErr = wshShellExec.StdErr
Do Until objStdOut.AtEndOfStream
standardout = standardout & objStdOut.ReadLine & vbCrlf
Loop
Do Until objStdErr.AtEndOfStream
errtext = errtext & objStdErr.ReadLine & vbCrlf
Loop
Однако, это не всегда работает.Если работающая программа записывает 4kb в stderr перед записью чего-либо в stdout, этот код зависает при оценке objStdOut.AtEndOfStream или objStdOut.ReadLine (обратите внимание, что вы не можете использовать objStdOut.ReadAll, потому что это также навсегда заблокирует).
Итак, я пришел к следующему решению, которое, кажется, работает:
strCommand = "c:\Windows\System32\cmd.exe /C StdOutTester.exe > " & rsltTextFile & " 2>&1 || call echo %^errorLevel% > " & rsltErrCodeFile
Set WshShellExec = WshShell.Exec(strCommand)
Do While WshShellExec.Status <> WshFinished
Wscript.Sleep(1000)
secCount = secCount+1
If secCount >= 10 Then 'kill children
If KillTaskChildren(WshShellExec.ProcessID) <> 0 Then
WScript.Echo "WMI Terminate Failed. Killing CMD..."
WshShellExec.Terminate
End If
End If
Loop
Для этого нужно запустить текущую задачу в другом окне cmd и перенаправить оба stdout / stderr в файл (итакже код ошибки, если применимо).Поскольку я запускаю команду в другом окне cmd, stdout и stderr отделены от объекта WshShellExec.Это также позволяет мне убить запущенную задачу за время ожидания (реальное, то есть не окно cmd, а реальная задача, с помощью WMI).
Итак, мой вопрос становится таким:
Поскольку я запускаю другое окно cmd.exe, возможно, что приглашение cmd само сталкивается с той же проблемой, если записывает достаточно данных в stdout / stderr (в этом случае моя логика тайм-аута должна его убить)?Записывает ли он что-нибудь в stdout / stderr?Как насчет того, чтобы использовать параметр / Q?