Process and WaitForExit instead of

I'm trying to run a program from PowerShell, wait for the exit, then get access to the ExitCode, but not having much luck. I don't want to use -Wait with Start-Process, as I need some processing to carry on in the background.

Here's a simplified test script:

cd "C:Windows"

# ExitCode is available when using -Wait...
Write-Host "Starting Notepad with -Wait - return code will be available"
$process = (Start-Process -FilePath "notepad.exe" -PassThru -Wait)
Write-Host "Process finished with return code: " $process.ExitCode

# ExitCode is not available when waiting separately
Write-Host "Starting Notepad without -Wait - return code will NOT be available"
$process = (Start-Process -FilePath "notepad.exe" -PassThru)
$process.WaitForExit()
Write-Host "Process exit code should be here: " $process.ExitCode

Running this script will cause notepad to be started. After this is closed manually, the exit code will be printed, and it will start again, without using -wait. No ExitCode is provided when this is quit:

Starting Notepad with -Wait - return code will be available
Process finished with return code:  0
Starting Notepad without -Wait - return code will NOT be available
Process exit code should be here: 

I need to be able to perform additional processing between starting the program and waiting for it to quit, so I can't make use of -Wait. Any idea how I can do this and still have access to the .ExitCode property from this process?


Two things you could do I think...

  • Create the System.Diagnostics.Process object manually and bypass Start-Process
  • Run the executable in a background job (only for non-interactive processes!)
  • Here's how you could do either:

    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "notepad.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = ""
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    #Do Other Stuff Here....
    $p.WaitForExit()
    $p.ExitCode
    

    OR

    Start-Job -Name DoSomething -ScriptBlock {
        & ping.exe somehost
        Write-Output $LASTEXITCODE
    }
    #Do other stuff here
    Get-Job -Name DoSomething | Wait-Job | Receive-Job
    

    There are two things to remember here. One is to add the -PassThru argument and two is to add the -Wait argument. You need to add the wait argument because of this defect http://connect.microsoft.com/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property

    -PassThru [<SwitchParameter>]
        Returns a process object for each process that the cmdlet started. By d
        efault, this cmdlet does not generate any output.
    

    Once you do this a process object is passed back and you can look at the ExitCode property of that object. Here is an example:

    $process = start-process ping.exe -windowstyle Hidden -ArgumentList "-n 1 -w 127.0.0.1" -PassThru -Wait
    $process.ExitCode
    
    # this will print 1
    

    If you run it without -PassThru or -Wait, it will print out nothing.

    Same answer here: https://stackoverflow.com/a/7109778/17822


    While trying out the final suggestion above, I discovered an even simpler solution. All I had to do was cache the process handle. As soon as I did that, $process.ExitCode worked correctly. If I didn't cache the process handle, $process.ExitCode was null.

    example:

    $proc = Start-Process $msbuild -PassThru
    $handle = $proc.Handle # cache proc.Handle http://stackoverflow.com/a/23797762/1479211
    $proc.WaitForExit();
    
    if ($proc.ExitCode -ne 0) {
        Write-Warning "$_ exited with status code $($proc.ExitCode)"
    }
    
    链接地址: http://www.djcxy.com/p/89652.html

    上一篇: 如何计划用户登录或不在PowerShell中的任务?

    下一篇: Process和WaitForExit而不是