HOWTO · PowerShell

如何從 PowerShell 中的 Start-Process 獲取退出代碼

本文將解釋如何在使用 start-process cmdlet 執行腳本後獲取退出代碼。

本頁內容

若要透過 PowerShell 的 Start-Process 取得程序的結束代碼,請使用 -PassThru 取得程序物件,並用 -Wait 等待程序結束,接著讀取它的 ExitCode 屬性:

$pwshPath = (Get-Process -Id $PID).Path
$workingDirectory = [System.IO.Path]::GetTempPath()
$process = Start-Process -FilePath $pwshPath -ArgumentList @('-NoProfile', '-Command', 'exit 7') -WorkingDirectory $workingDirectory -Wait -PassThru
"Exit code: $($process.ExitCode)"
Exit code: 7

此範例會在暫存工作目錄中啟動目前的 PowerShell 執行檔,並要求子程序傳回結束代碼 7。使用目前的執行檔可避免依賴 cmd.exe 等僅限 Windows 的程式;明確指定工作目錄,也能避免依賴呼叫者目前所在的目錄。請將執行檔和引數換成你要執行的程式。-Wait 會讓 PowerShell 等待程序完成,而 -PassThru 會傳回程序物件,供你讀取其 ExitCode。依慣例,結束代碼 0 表示成功;其他非零值的意義則由程式定義。範例輸出中的標籤是英文 Exit code,因為輸出區塊保持原樣。

使用 -Wait 和 -PassThru 取得結束代碼

如果指令碼接下來的處理取決於已啟動程式的結果,請同時使用這兩個參數。-Wait 控制 PowerShell 何時繼續執行,-PassThru 則提供程序物件。程序結束後讀取 ExitCode,即可取得它的最終結果。

將 $process.ExitCode 指派給 $exitCode,並在決定指令碼後續動作前,先將它與 0 比較。請依照程式文件所列的結束代碼調整條件。非零值沒有通用的固定意義;它可能表示錯誤,也可能代表程式文件中定義的其他結果。

為什麼 $LastExitCode 不會回報 Start-Process 啟動程序的結束代碼

Start-Process 不會設定 $LastExitCode。這個變數會回報目前 PowerShell 工作階段中,最近一次直接呼叫的原生程式結束時所傳回的代碼。使用 Start-Process 啟動另一個程序,不會讓該程序的結束代碼透過 $LastExitCode 取得。

請改用 Start-Process -PassThru 傳回之程序物件的 ExitCode 屬性。如果你直接呼叫原生程式,該程式結束時 PowerShell 會更新 $LastExitCode;這是另一種呼叫方式,無法用來取得透過 Start-Process 啟動之程序的結果。

使用 WaitForExit() 從程序物件取得結束代碼

你也可以省略 -Wait,保留程序物件,並在讀取 ExitCode 前呼叫它的 WaitForExit() 方法。若你需要先處理其他工作,再等待程序結束,這種方式就很有用。此方法會封鎖目前的執行流程,直到該程序結束。

等效的步驟是:使用 -PassThru 啟動程序、呼叫 WaitForExit(),然後讀取 $process.ExitCode。請保留與目標程序相對應的程序物件;這種方式不適用 $LastExitCode。隨附資料沒有這個替代方式的執行證據,因此本文不提供其獨立的輸出紀錄。

結論

對於透過 Start-Process 啟動的程序,請搭配使用 -PassThru 和 -Wait,再讀取傳回物件的 ExitCode 屬性。你也可以先對該物件呼叫 WaitForExit(),再讀取屬性。$LastExitCode 適用於從 PowerShell 直接呼叫的原生程式,不適用於透過 Start-Process 啟動的程序。