如何编写PowerShell脚本重启程序后仅关闭窗口不终止进程
代码失效核心原因
你的代码里有几个低级错误导致窗口关闭逻辑完全不运行:
- 两次尝试的代码都在
Start-Process启动程序后立刻写了exit命令,脚本执行到这一步就直接退出,后面所有关闭窗口的代码永远不会被执行 - 第二段代码创建COM对象时拼写错误,正确的ProgID是
WScript.Shell,你写成了Wsscript.Shell,会直接触发对象创建失败错误 AppActivate参数传错:你填的"ACVT.exe"既和你运行的ACMON进程名不匹配,也不是程序窗口的实际标题,根本无法定位到目标窗口- 调用
[System.Windows.Forms.SendKeys]前没有加载对应程序集,在默认PowerShell环境中会直接报错 - 固定1秒等待时长不可靠:程序冷启动时窗口加载可能超过1秒,此时发送按键会打空
可直接运行的修正脚本
这个脚本会等待目标窗口实际加载完成后再发送按键,避免因为启动延迟、窗口标题不匹配导致失效:
# 终止已运行的ACMON进程 Get-Process -Name "ACMON" -ErrorAction SilentlyContinue | Stop-Process -Force # 启动新的ACMON实例,-PassThru参数会返回进程对象,方便后续精准定位窗口 $acmonProc = Start-Process -FilePath "C:\Program Files\WindowsApps\B9ECED6F.Splendid_1.0.15.0_x64__qmba6cd70vzyy\ACMON.exe" -PassThru # 加载发送按键所需的程序集 Add-Type -AssemblyName System.Windows.Forms, Microsoft.VisualBasic # 循环等待程序主窗口加载,最多等待10秒防止脚本卡死 $maxWaitSeconds = 10 $stopwatch = [Diagnostics.Stopwatch]::StartNew() while ($stopwatch.Elapsed.TotalSeconds -lt $maxWaitSeconds -and -not $acmonProc.MainWindowHandle) { Start-Sleep -Milliseconds 200 $acmonProc.Refresh() } # 确认窗口存在后执行关闭操作 if ($acmonProc.MainWindowHandle) { # 按进程ID激活窗口,不需要匹配窗口标题,准确率更高 [void][Microsoft.VisualBasic.Interaction]::AppActivate($acmonProc.Id) Start-Sleep -Milliseconds 200 # 发送Alt+F4,仅关闭前台窗口,不会终止后台运行的进程 [System.Windows.Forms.SendKeys]::SendWait("%{F4}") }
注意事项
- 脚本里去掉了多余的
exit命令,所有逻辑会按顺序执行 - 如果你手动按Alt+F4确实是让程序最小化到后台托盘、不终止进程,这个脚本的效果和手动操作完全一致
- 200毫秒轮询一次窗口句柄的逻辑比固定等待的兼容性好很多,不要随意改回固定长等待
内容的提问来源于stack exchange,提问作者annoying_learner
相关产品推荐
相关产品推荐

