如何识别WM_QUERYENDSESSION与WM_ENDSESSION消息的发起源(Winlogon.exe或其他应用)
区分WM_QUERYENDSESSION/WM_ENDSESSION的发起进程(Winlogon vs 其他应用)
要判断这两个消息是否由Winlogon.exe发起,核心思路是获取发送消息的进程信息,具体实现可按以下步骤操作:
实现逻辑
- 在消息处理函数中,先获取发送消息的窗口所属线程ID,再通过线程ID得到对应进程ID
- 根据进程ID打开目标进程,读取进程名称后判断是否为
winlogon.exe
代码示例
首先需要引入必要的头文件和库:
#include <windows.h> #include <psapi.h> #include <string.h> #pragma comment(lib, "psapi.lib")
修改窗口过程函数,添加进程判断逻辑:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_QUERYENDSESSION: case WM_ENDSESSION: { DWORD senderProcessId = 0; // 获取发送消息的窗口所属线程对应的进程ID GetWindowThreadProcessId(hwnd, &senderProcessId); // 打开进程,需申请查询信息和读取内存的权限 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, senderProcessId); if (hProcess != NULL) { char processPath[MAX_PATH] = {0}; // 获取进程的可执行文件完整路径 GetModuleFileNameExA(hProcess, NULL, processPath, MAX_PATH); // 从路径中截取进程名称 char* processName = strrchr(processPath, '\\'); if (processName != NULL) { processName++; // 跳过路径最后的反斜杠 // 不区分大小写比较进程名 if (_stricmp(processName, "winlogon.exe") == 0) { // 消息来自Winlogon.exe,可添加对应处理逻辑 } else { // 消息来自其他应用,执行对应分支逻辑 } } CloseHandle(hProcess); } // 保留原有的消息返回逻辑 return TRUE; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } }
注意事项
- 权限兼容:普通用户权限通常可读取Winlogon的进程信息,若在严格权限环境下运行,需确保应用具备足够权限
- 字符串匹配:使用
_stricmp做不区分大小写的比较,避免因系统进程名大小写差异导致判断错误 - 系统兼容性:该方法适用于Windows XP及以上所有主流版本,PSAPI相关函数行为一致
内容的提问来源于stack exchange,提问作者user22394299
相关产品推荐
相关产品推荐

