Дождаться окончания процесса
У меня есть скрипт powershell, который автоматически печатает все файлы.pdf в папке с Foxit. Я установил ожидание выхода Foxit, пока сценарий не продолжится. Время от времени скрипт останавливается и ждет, даже если Foxit уже вышел. Есть ли способ сделать это тайм-аут после определенного количества времени?
Вот код, который у меня есть:
Start-Process $foxit -ArgumentList $argument -Wait
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry
Я попробовал рекомендации здесь, и они, кажется, не работают. Например, если я делаю:
$proc = Start-Process $foxit -ArgumentList $argument
$proc.WaitForExit()
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry
Я получил:
You cannot call a method on a null-valued expression.
Любая помощь будет принята с благодарностью.
3 ответа
Я думаю, что я понял это. Если я начну с Invoke-WmiMethod
Я могу получить идентификатор процесса и дождаться его, а затем попросить перевести его на тайм-аут.
$proc = Invoke-WmiMethod -Class win32_process -Name create -ArgumentList "$foxit $argument"
Wait-Process -Id $proc.ProcessId -Timeout 120
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry
Это, кажется, работает довольно последовательно.
Один из способов реализовать тайм-аут - использовать фоновое задание:
$Job = start-job -ScriptBlock { write-output 'start';Start-Sleep -Seconds 15 }
$timeout = New-TimeSpan -Seconds 10
$timer = [diagnostics.stopwatch]::StartNew()
While ($timer.Elapsed -le $timeout)
{
if ($Job.State -eq 'Completed' )
{
Receive-Job $Job
Remove-Job $Job
Return
}
Start-Sleep -Seconds 1
}
write-warning 'Job timed out. Stopping job'
Stop-Job $Job
Receive-Job $Job
Remove-Job $Job
Я столкнулся с этой же проблемой и нашел немного более простое решение, которое также фиксирует выходные данные дочернего процесса. -PassThru
Аргумент является ключевым, поскольку он возвращает объект процесса для каждого процесса, запускаемого командлетом.
$proc = Start-Process $foxit -ArgumentList $argument -PassThru
Wait-Process -Id $proc.Id -Timeout 120
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry
Я предпочитаю этот стиль, чтобы лучше контролировать, что делать во время выполнения внешнего процесса:
$waitTime = 60
$dism = Start-Process "$env:windir\system32\dism.exe" -ArgumentList "/Online /Cleanup-Image /ScanHealth" -PassThru -WindowStyle Hidden
while (!$dism.HasExited -or $waitTime -gt 0) {sleep -Seconds 1; $waitTime--}
"done."
Установив флажок для атрибута HasExited, я могу продолжить свой код параллельно с любыми другими задачами.