gpt4 book ai didi

powershell - Start-Process 不能很好地与 Start-Sleep 配合使用

转载 作者:行者123 更新时间:2023-12-02 23:34:36 29 4
gpt4 key购买 nike

我的目标是运行多个进程并保存它们的 ProcessNameId供以后使用。这是我的代码

[System.Collections.ArrayList]$startedProcesses = @()
$processStatus = Start-Process -FilePath notepad.exe -passthru
Start-Sleep 1
$startedProcesses.add($processStatus)

$processStatus = Start-Process -FilePath calc.exe -passthru
Start-Sleep 1
$startedProcesses.add($processStatus)

echo $startedProcesses

该脚本的输出是:
PS C:\Users\wakatana\Desktop\> .\so_question0.ps1

Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
235 15 3408 14112 0.08 24812 2 notepad
0 0 0 0.13 21460

我也试过替换 [System.Collections.ArrayList]$startedProcesses = @()$startedProcesses = New-Object System.Collections.Generic.List[System.ComponentModel.Component]但我以同样的结果结束。

问题:为什么我没有 calcProcessName 下?如果我删除 Start-Sleep 1然后我得到了 calcProcessName 下.这是为什么?这是启动应用程序的正确方式还是我做错了什么?我的操作系统:Windows 10 家庭版

最佳答案

您的问题与 Start-Sleep 的使用无关.
相反,问题在于,从 Windows 10 开始, calc.exe只是最终启动的进程的 stub 可执行文件, stub 进程在启动真正的可执行文件后立即退出 .
如果您删除 Start-Sleep Start-Process之间的通话和 echo调用,包含在 $startedProcesses 中的 stub 进程对象通常确实反射(reflect)了 stub 可执行文件的名称 - calc.exe - 在 ProcessName当时的专栏,由于仍然活着(尽管只是短暂的),但您仍然无法跟踪真正的可执行文件的进程生命周期并通过该对象退出代码。
真正的可执行文件的名字是Calculator.exe ,其确切路径包含完整的 AppX 包名称(包名称、版本号和发布者 ID):
例如,在启动 calc.exe 之后, (Get-Process Calculator).Path产生类似的东西:

C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe\Calculator.exe
但是,即使您知道该路径,也不能使用它直接启动 Calculator。
计算器,作为 AppX 包(通常通过 Microsoft Store 分发的 UWP 应用程序) , 看起来一定是 由其 URL 协议(protocol)方案 启动:[1]
Start-Process ms-calculator:
不幸的是,从 PowerShell (Core) 7.2/Windows PowerShell v5.1 开始, 添加 -PassThru使用 Start-Process 调用 AppX 包 URL导致错误 而不是返回一个代表已启动进程的对象——尽管 Calculator 仍会启动; 这同样适用于 -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 issue #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 most recently launched instance is used.
$processStatus = (Get-Process -Name Calculator | Sort-Object TotalProcessTime)[0]
注意:此方法并非万无一失,因为假设另一个进程可以同时启动一个 Calculator 实例,但在实践中应该足够健壮。

[1] 通过包名称或基于通配符的部分自动发现 AppX 应用程序的协议(protocol)名称 - 例如, *Calculator* ,见 this answer .

关于powershell - Start-Process 不能很好地与 Start-Sleep 配合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58721461/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com