2016-04-29 6 views
2

Ich möchte ein Programm in einer Schleife wiederholt ausführen.Powershell Start Prozess, Warte mit Timeout, Kill und Get Exit Code

Manchmal stürzt das Programm ab, also möchte ich es töten, damit die nächste Iteration korrekt starten kann. Ich ermittle dies über Timeout.

Ich habe das Timeout funktioniert aber kann nicht den Exit-Code des Programms, die ich auch, um sein Ergebnis zu bestimmen.

Vorher habe ich nicht mit Timeout gewartet, sondern nur -warte in Start-Process, aber das hat das Skript hängen gelassen, wenn das gestartete Programm abgestürzt ist. Mit diesem Setup konnte ich den Exit-Code jedoch korrekt erhalten.

Ich ausführe von 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 
    } 
} 

Wie kann ich

  1. starten Prozess
  2. warten, bis es ordentlich auszuführen und
  3. es Töten beenden, wenn es abgestürzt ist (zB schlägt Timeout)
  4. get Exit-Code des Prozesses
+0

[Wie warten und einen Timeout-Prozess in Powershell töten] (https: //stackoverflow.com/q/19532998/995714) –

Antwort

5

Sie können den Prozess mehr si beenden mply unter Verwendung $proc | kill oder $proc.Kill(). Seien Sie sich bewusst, dass Sie nicht in der Lage sein wird, einen Exit-Code in diesem Fall abzurufen, sollten Sie eher aktualisieren nur die interne Fehlerzähler:

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

Vielen Dank! Der Wait-Prozess wartet in Ihrer Lösung korrekt auf 400s, aber die "# beende den Prozess" -Klausel trifft nach dem Timeout nie - also wird auch der Prozess nie beendet, und nach der nächsten Iteration laufen 2 Prozesse. (Ich habe mit einem kleinen Timeout getestet, um diesen Fall zu erzwingen.) –

+1

Sie haben recht, ich dachte, Wait-Process würde etwas zurückgeben. Ich habe meine Antwort bearbeitet, nun ordne ich die Fehlermeldung $ timeout zu und im Falle eines Timeouts wird sie gesetzt. –

+0

Danke! (Es gab einen kleinen Tippfehler.) Großartig! –

Verwandte Themen