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 的程序;显式指定工作目录也可避免依赖调用者当前所在的目录。请将可执行文件和参数替换为你要运行的程序。示例输出显示英文标签 Exit code: 7;由于代码和输出块必须与原文逐字节一致,该标签保持英文。-Wait 会让 PowerShell 等待进程完成,-PassThru 会返回进程对象,以便读取其 ExitCode。按照惯例,退出代码 0 表示成功;任何非零值的含义由具体程序定义。

使用 -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 启动的进程。