web-dev-qa-db-fra.com

Processus de démarrage Powershell, attente avec délai d'attente, suppression et obtention du code de sortie

Je veux exécuter plusieurs fois un programme en boucle.

Parfois, le programme plante, donc je veux le tuer pour que la prochaine itération puisse démarrer correctement. Je le détermine via timeout.

J'ai le timeout qui fonctionne mais je ne peux pas obtenir le code de sortie du programme, dont j'ai également besoin pour déterminer son résultat.

Avant, je n'attendais pas avec timeout, mais j'utilisais juste -wait dans Start-Process, mais cela faisait que le script se bloquait si le programme démarré plantait. Avec cette configuration, j'ai pu obtenir correctement le code de sortie.

J'exécute depuis 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
    }
}

Comment puis-je

  1. Lancer un processus
  2. Attendez qu'il s'exécute et se termine correctement
  3. Tuez-le s'il tombe en panne (par exemple, délai d'expiration du hit)
  4. obtenir le code de sortie du processus
11
Andreas Reiff

Vous pouvez terminer le processus plus simplement en utilisant $proc | kill Ou $proc.Kill(). Sachez que vous ne pourrez pas récupérer de code de sortie dans ce cas, vous devriez plutôt simplement mettre à jour le compteur d'erreurs interne:

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 -ErrorAction SilentlyContinue -ErrorVariable timeouted

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

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