Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell Start Process, Wait with Timeout, Kill and Get Exit Code

I want to repeatedly execute a program in a loop.

Sometimes, the program crashes, so I want to kill it so the next iteration can correctly start. I determine this via timeout.

I have the timeout working but cannot get the Exit Code of the program, which I also need to determine its result.

Before, I did not wait with timeout, but just used -wait in Start-Process, but this made the script hang if the started program crashed. With this setup I could correctly get the exit code though.

I am executing from 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
    }
}

How can I

  1. Start a process
  2. Wait for it to orderly execute and finish
  3. Kill it if it is crashed (e. g. hits timeout)
  4. get exit code of process
like image 466
Andreas Reiff Avatar asked Apr 29 '16 08:04

Andreas Reiff


People also ask

How do I get the exit code in PowerShell?

Use the command Exit $LASTEXITCODE at the end of the powershell script to return the error codes from the powershell script. $LASTEXITCODE holds the last error code in the powershell script. It is in form of boolean values, with 0 for success and 1 for failure.

How do you wait for a process to finish in PowerShell?

The Wait-Process cmdlet waits for one or more running processes to be stopped before accepting input. In the PowerShell console, this cmdlet suppresses the command prompt until the processes are stopped. You can specify a process by process name or process ID (PID), or pipe a process object to Wait-Process .

What is process in PowerShell?

The process block is where the work is done in a PowerShell advanced function. There are two different approaches we need to keep in mind and account for. The first is how you handle parameters and the second is pipeline input into your function. The PROCESS block can be used without the BEGIN or END blocks.

How can I get the exit code from the PowerShell command?

How can I get the exit code from the following PowerShell command?: Start - Process - FilePath "C:WindowsSystem32robocopy.exe" - ArgumentList "C:Bogus Folder", "C:Target", / MIR - Wait. The above example should return an exit code of 16. Tuesday, November 9, 2010 1:35 AM.

What are the examples of PowerShell wait?

Let us discuss examples of PowerShell Wait. 1. Wait-Process Example When we use the command Wait-Process, it waits for the particular process or application to be stopped. This command accepts the Process ID, Name, and the Timeout in seconds.

How to use timeout command in PowerShell?

This is a cmd command but can be accessible in PowerShell as well. Once you specify the Timeout in seconds, the next commands wait until the timeout. Users can interrupt in the timeout specified if you want uninterrupted Timeout then use /NoBreak switch. The only option with the /NoBreak switch is to press Ctrl+C to terminate further execution.

How do I write output after 5 seconds in PowerShell?

Write-Output “This command will be executed after 5 seconds” You can also provide the -milliseconds parameter. This is a cmd command but can be accessible in PowerShell as well. Once you specify the Timeout in seconds, the next commands wait until the timeout.


1 Answers

You can terminate the process more simply using $proc | kill or $proc.Kill(). Be aware, that you won't be able to retrieve a exit code in this case, you should rather just update the internal error counter:

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
    }
}
like image 127
Martin Brandl Avatar answered Sep 23 '22 01:09

Martin Brandl