1 回答

TA贡献1856条经验 获得超17个赞
博士
// Make PowerShell not only launch Calculator, but also
// determine and output its PID, as described in the next section.
out, _ :=
exec.Command(
`powershell.exe`,
`-NoProfile`,
`-Command`,
`Start-Process -ErrorAction Stop calculator: ; (Get-Process Calculator | Where-Object SessionId -eq (Get-Process -ID $PID).SessionId).ID`,
).Output()
// Parse stdout output, which contains the PID, into an int
var pid int
fmt.Sscanf(string(out), "%d\n", &pid)
原则上,您可以传递
-PassThru
给 PowerShell 的Start-Process
(start
) cmd,它返回一个 process-info 对象,该对象具有.Id
包含已启动进程的 PID 的属性,并输出后者。不幸的是,对于特定的UWP/AppX 应用程序,例如计算器,这不起作用,这是底层 .NET API 中存在的问题,至少在 .NET 6.0 之前 - 请参阅GitHub 问题 #10996。
您可以尝试以下解决方法:
使用 启动 AppX 应用程序
Start-Process
,这会间接创建一个名为Calculator
(Windows 10) /CalculatorApp
(Windows 11) 的进程。如果您在启动计算器后运行,您可以自己识别此名称
(Get-Process *calc*).Name
。Get-Process *calc* | Select-Object Name, Path
也会显示可执行文件路径,但请注意,此可执行文件应被视为实现细节,不能直接调用。Calculator
返回那个/进程的 IDCalculatorApp
。事实上,计算器只在给定的用户会话中创建一个这样的进程,这实际上使得识别该进程变得容易。请注意,这意味着可能会返回预先存在的计算器进程的 PID ,但这是正确的,因为通过简单地将新计算器窗口的创建委托给现有进程启动的瞬态进程。
Start-Process
如果您想识别新创建的窗口,则需要做更多的工作:您必须枚举进程的窗口并识别具有最高 z 顺序的窗口。
PowerShell 代码(注意:在 Windows 11 中,替换Calculator
为CalculatorApp
):
# Launch Calculator - which may reuse an existing instance and
# merely create a new *window* - and report the PID.
Start-Process -ErrorAction Stop calculator:
(Get-Process Calculator | Where-Object SessionId -eq (Get-Process -ID $PID).SessionId).ID
请注意,我使用 URL 方案calculator:作为启动计算器的更简单方法。
笔记:
防止
Where-Object SessionId -eq (Get-Process -ID $PID).SessionId
错误地考虑其他用户在他们自己的会话Calculator
中创建的潜在进程(返回所有用户会话中在本地计算机上运行的所有进程)。按 过滤,即按活动用户会话(窗口站)过滤,可防止出现此问题。Get-Process
.SessionID
作为 PowerShell CLI调用:
powershell.exe -NoProfile -Command "Start-Process -ErrorAction Stop calculator: ; (Get-Process Calculator | Where-Object SessionId -eq (Get-Process -ID $PID).SessionId).ID"
- 1 回答
- 0 关注
- 357 浏览
添加回答
举报