您的问题与使用无关Start-Sleep
.
相反,问题是,从 Windows 10 开始,calc.exe
只是一个stub最终启动的进程的可执行文件,存根进程在启动真正的可执行文件后立即退出.
如果您删除Start-Sleep
之间的呼叫Start-Process
和echo
来电、stub过程对象包含在$startedProcesses
通常确实反映了存根可执行文件的名称 -calc.exe
- 在里面ProcessName
当时的专栏,由于还活着(尽管很短),但你仍然无法追踪real可执行文件的进程生命周期和通过该对象的退出代码。
真正的可执行文件的名称是Calculator.exe
,其确切路径包含完整的 AppX 包名称(包名称、版本号和发布者 ID):
例如,启动后calc.exe
, (Get-Process Calculator).Path
产生类似:
C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe\Calculator.exe
然而,您不能使用该路径来启动计算器directly- 你会得到一个Access denied
错误,即使在海拔高度运行时也是如此。
计算器,作为AppX 包(通常通过 Microsoft Store 分发的 UWP 应用程序), 最容易由其 URL 方案启动:
Start-Process ms-calculator:
Note:
-
通过包名称或基于通配符的部分自动发现 AppX 应用程序的 URL 方案名称 - 例如,*Calculator*
- see 这个答案 https://stackoverflow.com/a/58733061/45375.
-
不太方便的替代方法是使用shell:
基于应用程序 AppID 的 URL - 请参阅这个答案 https://stackoverflow.com/a/68907604/45375.
不幸的是,从 PowerShell (Core) 7.2 / Windows PowerShell v5.1 开始,adding -PassThru
调用 AppX 包 URLStart-Process
结果是error而不是返回代表已启动进程的对象 - 尽管计算器仍然启动;这同样适用于-Wait
:
# Launches Calculator, but doesn't return a process object
# and reports an error instead:
PS> Start-Process ms-calculator: -PassThru
Start-Process : This command cannot be run completely because the system cannot find all the information required.
...
该问题已报告于GitHub 问题 #10996 https://github.com/PowerShell/PowerShell/issues/10996.
解决方法:
# Invoke the *stub executable* synchronously, so that
# the real executable has already been launched by the time
# the call returns.
Start-Process -Wait -FilePath calc.exe
# Now get the real process object, named 'Calculator'.
# The newly launched or a preexisting instance is used (see below).
$processStatus = Get-Process -Name Calculator |
Where-Object SessionId -eq (Get-Process -ID $PID).SessionId).ID
注意:计算器只创建one每个用户会话的进程(窗口站):如果进程已存在,则随后启动该进程的委托。