Windows 8/10 中活动 window 的进程名称
Name of process for active window in Windows 8/10
以下示例可靠地 return 编辑了与活动 window 关联的进程的名称,但不适用于较新的 modern/universal 应用程序,因为它 returns 辅助进程的名称 WWAHost.exe 在 Windows 8 和 ApplicationFrameHost.exe 在 Windows 10 而不是应用程序的名称。
HWND active_window = GetForegroundWindow();
GetWindowThreadProcessId(active_window, &active_process_id);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, active_process_id);
GetProcessImageFileName(active_process, image_name, 512);
对于 Windows 10,ApplicationFrameHost.exe 是创建 window 句柄的进程,也是由 GetWindowThreadProcessId() 获取 return 的进程,是否还有另一个 Win32 API 可用于获取通用应用程序处于活动状态的活动进程?
还尝试使用 GetApplicationUserModelId() 和 GetPackageFullName() 但没有成功,因为它们分别 return APPMODEL_ERROR_NO_APPLICATION 和 APPMODEL_ERROR_NO_PACKAGE 因为 active_process 句柄只是辅助进程而不是活动应用程序的进程。
根据 window 的 hwnd,用于获取 Modern/Universal 应用程序的进程名称的任何其他 APIs,或者找出通用应用程序的进程名称已激活。
提前致谢!
这是一个小型控制台应用程序,它持续显示有关当前前台 window 进程和存储进程(如果有)的信息(因此您可以轻松地在桌面上选择不同的 windows 来测试它) .
应用程序可以有一个可以跨越多个进程的 window 层次结构。我在这里所做的是搜索具有 'Windows.UI.Core.CoreWindow' class 名称的第一个子 window。
此应用程序使用 UIAutomation API(以及 #import 指令提供的智能指针、智能 BSTR 和智能 VARIANT)。我想你可以用标准 Windows SDK 做同样的事情,但我发现以这种方式使用的 UIAutomation 非常优雅。
#include "stdafx.h"
#import "UIAutomationCore.dll"
using namespace UIAutomationClient;
int main()
{
// initialize COM, needed for UIA
CoInitialize(NULL);
// initialize main UIA class
IUIAutomationPtr pUIA(__uuidof(CUIAutomation));
do
{
// get the Automation element for the foreground window
IUIAutomationElementPtr foregroundWindow = pUIA->ElementFromHandle(GetForegroundWindow());
wprintf(L"pid:%i\n", foregroundWindow->CurrentProcessId);
// prepare a [class name = 'Windows.UI.Core.CoreWindow'] condition
_variant_t prop = L"Windows.UI.Core.CoreWindow";
IUIAutomationConditionPtr condition = pUIA->CreatePropertyCondition(UIA_ClassNamePropertyId, prop);
// get the first element (window hopefully) that satisfies this condition
IUIAutomationElementPtr coreWindow = foregroundWindow->FindFirst(TreeScope::TreeScope_Children, condition);
if (coreWindow)
{
// get the process id property for that window
wprintf(L"store pid:%i\n", coreWindow->CurrentProcessId);
}
Sleep(1000);
} while (TRUE);
cleanup:
CoUninitialize();
return 0;
}
拍摄 运行 个进程的快照并通过比较进程 ID 从中提取名称是否行不通?
完整参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs.85).aspx
但是您使用 CreateToolhelp32Snapshot() 修复了快照。
或来自 WTSEnumerateProcesses() 和周围 API?
很确定它在 Win 8 中有效。它在 10 中是否损坏?
当你想对这样的东西进行逆向工程时,一定要使用 Spy++ 实用程序。包含在 Visual Studio 中,您需要 Common7\Tools\spyxx_amd64.exe 中的 64 位版本。使用“搜索”>“查找”Window 并将靶心拖动到 UWP 应用程序,例如天气。
您将看到使用 GetForegroundWindow() 找到的 window,它至少有 3 个子节点 windows:
- ApplicationFrameTitleBarWindow
- ApplicationFrameInputSinkWindow
- Windows.Core.UI.CoreWindow,这是 UWP 应用程序的主机 window,也是您感兴趣的应用程序。右键单击它并 select 属性,进程选项卡,单击进程 ID .这会将您带到您想知道的真实所有者流程。
所以你只需要从你已有的代码中多做一步,你只需要枚举子 windows 并寻找一个具有不同所有者进程的。一些 C 代码,试图在不做太多假设和没有足够的错误检查的情况下使其尽可能通用:
#include <stdio.h>
#include <Windows.h>
typedef struct {
DWORD ownerpid;
DWORD childpid;
} windowinfo;
BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp) {
windowinfo* info = (windowinfo*)lp;
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != info->ownerpid) info->childpid = pid;
return TRUE;
}
int main()
{
Sleep(2000);
HWND active_window = GetForegroundWindow();
windowinfo info = { 0 };
GetWindowThreadProcessId(active_window, &info.ownerpid);
info.childpid = info.ownerpid;
EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
WCHAR image_name[MAX_PATH] = { 0 };
DWORD bufsize = MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
wprintf(L"%s\n", image_name);
CloseHandle(active_process);
return 0;
}
天气程序的输出:
C:\Program Files\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe\
Microsoft.Msn.Weather.exe
从 Win10 周年更新开始 ApplicationFrameHost 子 window return 除了 UWP 应用程序。重新登录后,它仅在平板电脑模式下有效。
以下示例可靠地 return 编辑了与活动 window 关联的进程的名称,但不适用于较新的 modern/universal 应用程序,因为它 returns 辅助进程的名称 WWAHost.exe 在 Windows 8 和 ApplicationFrameHost.exe 在 Windows 10 而不是应用程序的名称。
HWND active_window = GetForegroundWindow();
GetWindowThreadProcessId(active_window, &active_process_id);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, active_process_id);
GetProcessImageFileName(active_process, image_name, 512);
对于 Windows 10,ApplicationFrameHost.exe 是创建 window 句柄的进程,也是由 GetWindowThreadProcessId() 获取 return 的进程,是否还有另一个 Win32 API 可用于获取通用应用程序处于活动状态的活动进程?
还尝试使用 GetApplicationUserModelId() 和 GetPackageFullName() 但没有成功,因为它们分别 return APPMODEL_ERROR_NO_APPLICATION 和 APPMODEL_ERROR_NO_PACKAGE 因为 active_process 句柄只是辅助进程而不是活动应用程序的进程。
根据 window 的 hwnd,用于获取 Modern/Universal 应用程序的进程名称的任何其他 APIs,或者找出通用应用程序的进程名称已激活。
提前致谢!
这是一个小型控制台应用程序,它持续显示有关当前前台 window 进程和存储进程(如果有)的信息(因此您可以轻松地在桌面上选择不同的 windows 来测试它) .
应用程序可以有一个可以跨越多个进程的 window 层次结构。我在这里所做的是搜索具有 'Windows.UI.Core.CoreWindow' class 名称的第一个子 window。
此应用程序使用 UIAutomation API(以及 #import 指令提供的智能指针、智能 BSTR 和智能 VARIANT)。我想你可以用标准 Windows SDK 做同样的事情,但我发现以这种方式使用的 UIAutomation 非常优雅。
#include "stdafx.h"
#import "UIAutomationCore.dll"
using namespace UIAutomationClient;
int main()
{
// initialize COM, needed for UIA
CoInitialize(NULL);
// initialize main UIA class
IUIAutomationPtr pUIA(__uuidof(CUIAutomation));
do
{
// get the Automation element for the foreground window
IUIAutomationElementPtr foregroundWindow = pUIA->ElementFromHandle(GetForegroundWindow());
wprintf(L"pid:%i\n", foregroundWindow->CurrentProcessId);
// prepare a [class name = 'Windows.UI.Core.CoreWindow'] condition
_variant_t prop = L"Windows.UI.Core.CoreWindow";
IUIAutomationConditionPtr condition = pUIA->CreatePropertyCondition(UIA_ClassNamePropertyId, prop);
// get the first element (window hopefully) that satisfies this condition
IUIAutomationElementPtr coreWindow = foregroundWindow->FindFirst(TreeScope::TreeScope_Children, condition);
if (coreWindow)
{
// get the process id property for that window
wprintf(L"store pid:%i\n", coreWindow->CurrentProcessId);
}
Sleep(1000);
} while (TRUE);
cleanup:
CoUninitialize();
return 0;
}
拍摄 运行 个进程的快照并通过比较进程 ID 从中提取名称是否行不通? 完整参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs.85).aspx
但是您使用 CreateToolhelp32Snapshot() 修复了快照。
或来自 WTSEnumerateProcesses() 和周围 API?
很确定它在 Win 8 中有效。它在 10 中是否损坏?
当你想对这样的东西进行逆向工程时,一定要使用 Spy++ 实用程序。包含在 Visual Studio 中,您需要 Common7\Tools\spyxx_amd64.exe 中的 64 位版本。使用“搜索”>“查找”Window 并将靶心拖动到 UWP 应用程序,例如天气。
您将看到使用 GetForegroundWindow() 找到的 window,它至少有 3 个子节点 windows:
- ApplicationFrameTitleBarWindow
- ApplicationFrameInputSinkWindow
- Windows.Core.UI.CoreWindow,这是 UWP 应用程序的主机 window,也是您感兴趣的应用程序。右键单击它并 select 属性,进程选项卡,单击进程 ID .这会将您带到您想知道的真实所有者流程。
所以你只需要从你已有的代码中多做一步,你只需要枚举子 windows 并寻找一个具有不同所有者进程的。一些 C 代码,试图在不做太多假设和没有足够的错误检查的情况下使其尽可能通用:
#include <stdio.h>
#include <Windows.h>
typedef struct {
DWORD ownerpid;
DWORD childpid;
} windowinfo;
BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp) {
windowinfo* info = (windowinfo*)lp;
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != info->ownerpid) info->childpid = pid;
return TRUE;
}
int main()
{
Sleep(2000);
HWND active_window = GetForegroundWindow();
windowinfo info = { 0 };
GetWindowThreadProcessId(active_window, &info.ownerpid);
info.childpid = info.ownerpid;
EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
WCHAR image_name[MAX_PATH] = { 0 };
DWORD bufsize = MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
wprintf(L"%s\n", image_name);
CloseHandle(active_process);
return 0;
}
天气程序的输出:
C:\Program Files\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe\ Microsoft.Msn.Weather.exe
从 Win10 周年更新开始 ApplicationFrameHost 子 window return 除了 UWP 应用程序。重新登录后,它仅在平板电脑模式下有效。