2016-04-29 9 views
2

Я хочу многократно выполнять программу в цикле.Powershell Start Process, Wait with Timeout, Kill и Get Exit Code

Иногда программа вылетает из строя, поэтому я хочу ее убить, чтобы следующая итерация могла начать правильно. Я определяю это с помощью тайм-аута.

У меня есть тайм-аут, но я не могу получить код выхода программы, который также должен определить его результат.

Раньше я не ждал с таймаутом, а просто использовал -wait в Start-Process, но это заставило скрипт зависать, если запущенная программа разбилась. С этой настройкой я мог бы правильно получить код выхода.

Выполняется с ISE.

for ($i=0; $i -le $max_iterations; $i++) 
{ 
    $proc = Start-Process -filePath $programtorun -ArgumentList $argumentlist -workingdirectory $programtorunpath -PassThru 
    # wait up to x seconds for normal termination 
    Wait-Process -Timeout 300 -Name $programname 
    # if not exited, kill process 
    if(!$proc.hasExited) { 
     echo "kill the process" 
     #$proc.Kill() <- not working if proc is crashed 
     Start-Process -filePath "taskkill.exe" -Wait -ArgumentList '/F', '/IM', $fullprogramname 
    } 
    # this is where I want to use exit code but it comes in empty 
    if ($proc.ExitCode -ne 0) { 
     # update internal error counters based on result 
    } 
} 

Как

  1. Начать процесс
  2. ждать, пока она упорядоченно выполнить и завершить
  3. убить его, если он разбился (например, хиты тайм-аута)
  4. Получить код выхода процесса
+0

[Как ждать и убить процесс ожидания в Powershell] (HTTPS: //stackoverflow.com/q/19532998/995714) –

ответ

5

Вы можете прекратить процесс больше si используя $proc | kill или $proc.Kill(). Имейте в виду, что вы не сможете получить код выхода в этом случае, вы должны достаточно просто обновить внутренний счетчик ошибок:

for ($i=0; $i -le $max_iterations; $i++) 
{ 
    $proc = Start-Process -filePath $programtorun -ArgumentList $argumentlist -workingdirectory $programtorunpath -PassThru 

    # keep track of timeout event 
    $timeouted = $null # reset any previously set timeout 

    # wait up to x seconds for normal termination 
    $proc | Wait-Process -Timeout 4 -ea 0 -ev timeouted 

    if ($timeouted) 
    { 
     # terminate the process 
     $proc | kill 

     # update internal error counter 
    } 
    elseif ($proc.ExitCode -ne 0) 
    { 
     # update internal error counter 
    } 
} 
+0

Спасибо! Wait-Process корректно ждет 400-х в вашем решении, но предложение «# terminate the process» никогда не попадает после таймаута - так что процесс никогда не убивается, а после следующей итерации выполняется 2 процесса. (Я проверил с небольшим таймаутом, чтобы заставить этот случай.) –

+1

Вы правы, я думал, что Wait-Process что-то вернет. Я отредактировал свой ответ, теперь я назначаю сообщение об ошибке $ timeouted, и в случае возникновения таймаута он установлен. –

+0

Спасибо! (Была небольшая опечатка.) Отлично работает! –