Powershell cmdlet Start-Process
行为异常:
当我启动另一个控制台进程并指定 -NoNewWindow
时,ExitCode 属性(int
!)为空。
这是一个测试:与 cmd
之外的其他东西相同。本次测试是在 Win10 和 PS5 上进行的,Win7 和 PS5 也一样:
PS C:\Users\Martin> cmd.exe /Cver
Microsoft Windows [Version 10.0.15063]
PS C:\Users\Martin> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.15063.296
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.15063.296
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\Users\Martin> $pNewWindow = Start-Process -FilePath "cmd.exe" -ArgumentList '/C"exit 42"' -PassThru
PS C:\Users\Martin> $pNewWindow.WaitForExit()
PS C:\Users\Martin> $pNoNewWindow.HasExited
True
PS C:\Users\Martin> $pNewWindow.ExitCode
42
PS C:\Users\Martin> $pNoNewWindow = Start-Process -FilePath "cmd.exe" -ArgumentList '/C"exit 42"' -PassThru -NoNewWindow
PS C:\Users\Martin> $pNoNewWindow.WaitForExit()
PS C:\Users\Martin> $pNoNewWindow.HasExited
True
PS C:\Users\Martin> $pNoNewWindow.ExitCode
PS C:\Users\Martin> $pNoNewWindow.ExitCode -eq $null
True
PS C:\Users\Martin> $pNoNewWindow | Get-Member | ? {$_.Name -imatch "exit"}
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Exited Event System.EventHandler Exited(System.Object, System.EventArgs)
WaitForExit Method bool WaitForExit(int milliseconds), void WaitForExit()
ExitCode Property int ExitCode {get;}
ExitTime Property datetime ExitTime {get;}
HasExited Property bool HasExited {get;}
PS C:\Users\Martin>
... 所以,属性在那里,但它是 null
,即使它是一个 int
?
最佳答案
来自 linked question 的回答的回答/评论:
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.
事实上,对于不会立即终止的进程(与示例中的 cmd.exe 不同),解决方法有效:
$proc = Start-Process -NoNewWindow -PassThru ...
$handle = $proc.Handle # cache proc.Handle https://stackoverflow.com/a/23797762/1479211
$proc.WaitForExit()
$proc.ExitCode ... will be set
用户在 comments 中添加了解释:
This is a quirk of the implementation of the .NET Process object. The implementation of the ExitCode property first checks if the process has exited. For some reason, the code that performs that check not only looks at the HasExited property but also verifies that the proces handle is present in the proces object and throws an exception if it is not. PowerShell intercepts that exception and returns null.
Accessing the Handle property causes the process object to retrieve the process handle and store it internally. Once the handle is stored in the process object, the ExitCode property works as expected.
自 Start-Process
无法启动暂停的进程,并且只有在进程运行时才能获取句柄(看起来),对于短时间运行的进程来说使用起来有点脆弱。
关于.net - Start-Process/System.Diagnostics.Process ExitCode 是 $null with -NoNewWindow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44057728/