如何获取Windows 10应用商店应用的进程ID/句柄?解决句柄异常问题
为什么获取应用商店应用时拿到的是ApplicationFrameHost句柄,以及如何获取目标应用句柄
这是Windows现代应用(UWP/应用商店应用)窗口管理中非常常见的问题,我来给你详细拆解原因和解决办法:
一、为什么拿到的是ApplicationFrameHost的句柄?
Windows应用商店的应用(UWP)采用沙箱化架构,这类应用本身并没有独立的顶层窗口——它们的UI内容是运行在系统提供的容器进程ApplicationFrameHost.exe中的。这个容器进程负责处理窗口边框、标题栏、系统级窗口交互等逻辑,而UWP应用的实际UI则作为子窗口嵌入到这个容器里。
当你通过常规窗口枚举API(比如EnumWindows)获取顶层窗口时,首先捕获到的就是这个容器进程的窗口,也就是ApplicationFrameHost的句柄。而窗口标题能显示目标应用名称,是因为ApplicationFrameHost会自动同步宿主UWP应用的标题信息,方便用户识别。
二、如何通过ApplicationFrameHost句柄获取目标应用(如Skype)的句柄?
答案是肯定的,你可以通过枚举ApplicationFrameHost窗口的子窗口,定位到UWP应用实际的核心窗口。具体步骤和代码示例如下:
核心思路
ApplicationFrameHost的窗口下会包含一个类名为Windows.UI.Core.CoreWindow的子窗口,这个窗口就是UWP应用实际的UI窗口,它的进程ID对应目标应用的进程(比如Skype的进程)。我们可以通过枚举子窗口的方式找到它。
代码示例(C++)
#include <windows.h> #include <wchar.h> // 枚举子窗口的回调函数 BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) { WCHAR className[256]; GetClassName(hwnd, className, ARRAYSIZE(className)); // 匹配UWP应用的核心窗口类名 if (wcscmp(className, L"Windows.UI.Core.CoreWindow") == 0) { *(HWND*)lParam = hwnd; return FALSE; // 找到目标窗口后停止枚举 } return TRUE; } // 从ApplicationFrameHost句柄获取UWP应用窗口句柄 HWND GetUwpWindowFromFrameHost(HWND frameHostHwnd) { HWND uwpHwnd = NULL; EnumChildWindows(frameHostHwnd, EnumChildProc, (LPARAM)&uwpHwnd); return uwpHwnd; }
补充说明
- 验证窗口归属:拿到
Windows.UI.Core.CoreWindow的句柄后,你可以用GetWindowThreadProcessId获取它的进程ID,再和目标应用的进程ID对比,确保是你要找的应用。 - 特殊情况处理:少数UWP应用可能有多个窗口或特殊的窗口结构,这时可能需要结合窗口标题、进程信息进一步筛选,但绝大多数常规应用商店应用都适用上述方法。
- 权限问题:确保你的程序有足够的权限枚举窗口,比如以管理员身份运行(如果目标应用是高权限的)。
内容的提问来源于stack exchange,提问作者Avishekh Bharati




