Programing

-Wait 대신 Start-Process 및 WaitForExit를 사용하여 ExitCode 얻기

lottogame 2020. 12. 14. 07:45
반응형

-Wait 대신 Start-Process 및 WaitForExit를 사용하여 ExitCode 얻기


PowerShell에서 프로그램을 실행하고 종료를 기다린 다음 ExitCode에 액세스하려고 시도하고 있지만 운이 좋지는 않습니다. 백그라운드에서 수행하기 위해 약간의 처리가 필요 하기 때문에 -Wait와 함께 사용하고 싶지 않습니다 Start-Process.

다음은 간단한 테스트 스크립트입니다.

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

이 스크립트를 실행하면 메모장 이 시작됩니다. 수동으로 닫으면 종료 코드가 인쇄되고를 사용하지 않고 다시 시작됩니다 -wait. 종료시 ExitCode가 제공되지 않습니다.

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:

프로그램 시작과 종료 대기 사이에 추가 처리를 수행 할 수 있어야하므로 사용할 수 없습니다 -Wait. 이 작업을 수행하고이 프로세스에서 .ExitCode 속성에 계속 액세스 할 수있는 방법은 무엇입니까?


당신이 할 수있는 두 가지 일이 ...

  1. System.Diagnostics.Process 개체를 수동으로 만들고 Start-Process를 무시합니다.
  2. 백그라운드 작업에서 실행 파일 실행 (비대화 형 프로세스에만 해당!)

다음 중 하나를 수행 할 수있는 방법은 다음과 같습니다.

$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

또는

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

여기서 기억해야 할 두 가지가 있습니다. 하나는 -PassThru인수 를 추가하는 것이고 두 번째는 -Wait인수 를 추가하는 것 입니다. 이 결함으로 인해 대기 인수를 추가해야합니다. 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.

이렇게하면 프로세스 개체가 다시 전달되고 해당 개체의 ExitCode 속성을 볼 수 있습니다. 다음은 그 예입니다.

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

# This will print 1

-PassThru또는 없이 실행하면 -Wait아무것도 인쇄되지 않습니다.

The same answer is here: How do I run a Windows installer and get a succeed/fail value in PowerShell?


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
$proc.WaitForExit();

if ($proc.ExitCode -ne 0) {
    Write-Warning "$_ exited with status code $($proc.ExitCode)"
}

The '-Wait' option seemed to block for me even though my process had finished.

I tried Adrian's solution and it works. But I used Wait-Process instead of relying on a side effect of retrieving the process handle.

So:

$proc = Start-Process $msbuild -PassThru
Wait-Process -InputObject $proc

if ($proc.ExitCode -ne 0) {
    Write-Warning "$_ exited with status code $($proc.ExitCode)"
}

Or try adding this...

$code = @"
[DllImport("kernel32.dll")]
public static extern int GetExitCodeProcess(IntPtr hProcess, out Int32 exitcode);
"@
$type = Add-Type -MemberDefinition $code -Name "Win32" -Namespace Win32 -PassThru
[Int32]$exitCode = 0
$type::GetExitCodeProcess($process.Handle, [ref]$exitCode)

By using this code, you can still let PowerShell take care of managing redirected output/error streams, which you cannot do using System.Diagnostics.Process.Start() directly.

참고URL : https://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait

반응형