You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断UWP应用是否处于带窗口运行状态?

问题原因

IPackageDebugSettings.GetPackageExecutionState返回PES_RUNNING是因为它反映的是应用包的执行状态,而非进程的实时运行状态。当UWP或打包桌面应用被系统后台挂起时,包实例并未终止,所以包状态仍为PES_RUNNING,但对应的进程会被标记为“Suspended”(暂停)。


目标1:未运行时挂起启动应用,已运行则触发错误

1. 精准判断应用的活跃状态

要区分“包存在但进程挂起”和“进程活跃运行”,需要结合包状态与进程状态双重校验:

  • 调用IPackageDebugSettings.GetPackageExecutionState:
    • 若返回PES_NOT_RUNNING:确认应用完全未启动,可执行挂起启动逻辑。
    • 若返回PES_RUNNING:进一步枚举该包的进程,检查进程是否处于挂起状态。
  • 枚举包进程并检测挂起状态:
    1. 使用GetPackageProcesses获取目标包对应的所有进程ID。
    2. 对每个进程ID,以PROCESS_QUERY_INFORMATION权限打开进程句柄。
    3. 通过NtQueryInformationProcess查询PROCESS_SUSPEND_COUNT:若挂起计数>0,说明进程处于暂停状态,可视为“未活跃运行”;若计数为0,说明应用正在活跃运行,触发错误。

2. 挂起启动应用

  1. 正常启动应用:根据应用类型选择合适的启动方式——UWP应用用LaunchUriAsync,桌面桥应用用ShellExecuteEx启动主EXE。
  2. 启动后立即挂起进程:
    • 轮询查找目标进程ID(或用WaitForInputIdle等待应用初始化完成)。
    • 以PROCESS_SUSPEND_RESUME权限打开进程句柄。
    • 调用NtSuspendProcess(需链接ntdll.lib或动态加载)将进程挂起。

目标2:后台活跃运行时优雅关闭应用

优雅关闭需避免强制终止,优先通过窗口消息触发:

  1. 枚举系统窗口,用GetWindowThreadProcessId匹配目标应用的进程ID。
  2. 识别主窗口(可通过窗口样式排除子窗口、弹窗),发送WM_CLOSE消息:
    SendMessage(hWnd, WM_CLOSE, 0, 0);
    
  3. 若应用无可视化窗口(纯后台进程),可尝试发送CTRL_CLOSE_EVENT信号,或通过进程句柄调用ExitProcess(需PROCESS_TERMINATE权限,仅作为备选)。

关键注意事项

  • 操作第三方打包应用需足够权限:需以管理员身份运行程序,同时获取进程查询、挂起/恢复的权限。
  • NtQueryInformationProcess和NtSuspendProcess属于未公开API,需手动包含ntdll.h并链接ntdll.lib,或通过GetProcAddress动态加载调用。
  • 不同打包类型(UWP、桌面桥)的启动逻辑略有差异,需根据目标应用类型调整。

内容的提问来源于stack exchange,提问作者LOST

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:02:38