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

使用SetWindowsHookEx监控窗口创建与销毁的问题求助

Troubleshooting Your WH_GETMESSAGE Hook for Window Creation/Deletion Monitoring

Hey there, let's break down why your WH_GETMESSAGE hook isn't behaving as expected and walk through the fixes you need to apply. The key differences between your working WH_KEYBOARD_LL hook and this WH_GETMESSAGE attempt are critical here—let's unpack them:

Core Issues in Your Current Code

1. WH_GETMESSAGE Hook Scope & Architecture

Unlike WH_KEYBOARD_LL (a low-level hook that works globally without DLL injection), WH_GETMESSAGE operates differently:

  • If you pass 0 as the last parameter to SetWindowsHookEx, it only hooks messages in your current thread—so you won't see messages from other windows/applications.
  • To monitor messages across all processes (like WM_CREATE/WM_DESTROY from any window), you need a global WH_GETMESSAGE hook, which requires your hook procedure to live inside a DLL. This is because other processes need to load the DLL to execute your hook code in their address space.

2. Incorrect GetModuleFileNameEx Usage

Your code calls GetModuleFileNameEx(m.hwnd, 0, Buffer, MAX_PATH)—but the first parameter of this function is a process handle, not a window handle. You need to:

  1. Get the process ID associated with the window using GetWindowThreadProcessId
  2. Open the process with OpenProcess to get a valid handle
  3. Then call GetModuleFileNameEx with that process handle

3. Broken Hook Chain & Unfiltered Messages

  • When wParam != PM_REMOVE, you return NULL instead of calling CallNextHookEx. This breaks the hook chain, preventing other hooks from receiving messages and can cause unexpected system behavior.
  • You're not filtering for WM_CREATE or WM_DESTROY—your code tries to process every message, which is inefficient and not what you intended.

Fixed Implementation

To make this work, you'll need two parts: a DLL containing the hook procedure, and a test application to set/release the hook.

Part 1: Hook DLL Code

#include <windows.h>
#include <tchar.h>
#include <psapi.h>

#pragma comment(lib, "psapi.lib")

HHOOK g_hHook = NULL;

// Hook procedure
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0 && wParam == PM_REMOVE)
    {
        MSG* pMsg = reinterpret_cast<MSG*>(lParam);
        
        // Filter for the messages we care about
        if (pMsg->message == WM_CREATE || pMsg->message == WM_DESTROY)
        {
            DWORD dwProcessId = 0;
            GetWindowThreadProcessId(pMsg->hwnd, &dwProcessId);
            
            // Open the process to get its module path
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
            if (hProcess != NULL)
            {
                TCHAR szExePath[MAX_PATH] = {0};
                if (GetModuleFileNameEx(hProcess, NULL, szExePath, MAX_PATH))
                {
                    TCHAR szMsg[512];
                    _stprintf_s(szMsg, _T("Window %s: %s"), 
                        (pMsg->message == WM_CREATE) ? _T("Created") : _T("Destroyed"), 
                        szExePath);
                    MessageBox(NULL, szMsg, _T("Window Event"), MB_ICONINFORMATION);
                }
                CloseHandle(hProcess);
            }
        }
    }

    // Always pass the message to the next hook in the chain
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

// Exported function to set the hook
extern "C" __declspec(dllexport) BOOL SetGlobalGetMsgHook()
{
    g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, GetModuleHandle(_T("MsgHook.dll")), 0);
    return (g_hHook != NULL);
}

// Exported function to release the hook
extern "C" __declspec(dllexport) void ReleaseGlobalGetMsgHook()
{
    if (g_hHook != NULL)
    {
        UnhookWindowsHookEx(g_hHook);
        g_hHook = NULL;
    }
}

// DLL entry point
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

Part 2: Test Application Code

#include <windows.h>
#include <tchar.h>

// Function prototypes for DLL exports
typedef BOOL(*SetHookFunc)();
typedef void(*ReleaseHookFunc)();

int _tmain()
{
    // Load the hook DLL
    HMODULE hDll = LoadLibrary(_T("MsgHook.dll"));
    if (hDll == NULL)
    {
        MessageBox(NULL, _T("Failed to load hook DLL!"), _T("Error"), MB_ICONERROR);
        return 1;
    }

    // Get pointers to the exported functions
    SetHookFunc SetHook = reinterpret_cast<SetHookFunc>(GetProcAddress(hDll, "SetGlobalGetMsgHook"));
    ReleaseHookFunc ReleaseHook = reinterpret_cast<ReleaseHookFunc>(GetProcAddress(hDll, "ReleaseGlobalGetMsgHook"));

    if (!SetHook || !ReleaseHook)
    {
        MessageBox(NULL, _T("Failed to get DLL functions!"), _T("Error"), MB_ICONERROR);
        FreeLibrary(hDll);
        return 1;
    }

    // Set the global hook
    if (!SetHook())
    {
        MessageBox(NULL, _T("Failed to install hook!"), _T("Error"), MB_ICONERROR);
        FreeLibrary(hDll);
        return 1;
    }

    MessageBox(NULL, _T("Hook installed successfully. Click OK to exit and release hook."), _T("Info"), MB_ICONINFORMATION);

    // Release the hook and unload DLL
    ReleaseHook();
    FreeLibrary(hDll);

    return 0;
}

Key Notes for Success

  • Compile the DLL as a 32-bit or 64-bit binary to match the target processes (e.g., 32-bit DLL for 32-bit apps, 64-bit for 64-bit apps—you can't mix architectures).
  • Run the test application with administrative privileges—some processes may require elevated rights to hook.
  • Be cautious with global hooks—they can impact system performance if not optimized, and misbehaving hooks can cause instability.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:40:09