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

WIN API键盘钩子按键记录器:GetMessage阻塞与定时停止问题

问题原因分析与解决方案

核心原因

WH_KEYBOARD_LL是Windows的低级别键盘钩子,它的工作逻辑和普通钩子有本质区别:

  • 系统不会直接触发你的钩子回调kbHook,而是把键盘事件封装成消息,发送到安装钩子的线程的消息队列里。
  • 只有当该线程调用GetMessage、PeekMessage这类消息处理函数时,系统才会在处理消息的间隙触发钩子回调,让你处理按键事件。

你之前的操作完全违背了这个逻辑:

  1. 设置钩子后直接调用Sleep(10000),线程休眠期间根本不会处理消息队列,所以钩子回调一次都不会执行,自然生成不了日志。
  2. 休眠结束后卸载钩子,再进入GetMessage循环——这时候钩子已经不存在,消息队列里也没有键盘事件消息,GetMessage会一直阻塞等待新消息,程序就僵住了。

正确实现方式

要让程序在指定时间后停止,必须在保持消息循环运行的同时检查超时条件,下面给出两种可行方案:

方案1:在消息循环中检查运行时长

int keylogger_main()
{
    char path[] = "D:\\winApiFiles\\key_logs.txt";
    DeleteFileA(path);

    MSG msg;
    HHOOK hHook = NULL;

    time_t start_time = time(NULL);
    const int RUN_SECONDS = 10; // 设定运行10秒

    hHook = SetWindowsHookEx(WH_KEYBOARD_LL, kbHook, NULL, 0);
    if (hHook == NULL)
    {
        printf("HOOK FAILED");
        return 1;
    }

    // 消息循环中同时监控运行时间
    while (GetMessage(&msg, NULL, 0, 0))
    {
        // 计算已运行时间,达到设定值就退出循环
        if (difftime(time(NULL), start_time) >= RUN_SECONDS)
        {
            break;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(hHook);
    printf("Key logs saved to: %s", path);
    return 0;
}

方案2:用Windows定时器触发停止

通过SetTimer创建定时器,指定时间后系统会发送WM_TIMER消息,收到消息就退出循环:

// 用全局/静态变量保存钩子句柄,方便后续卸载
static HHOOK g_hHook;

int keylogger_main()
{
    char path[] = "D:\\winApiFiles\\key_logs.txt";
    DeleteFileA(path);

    MSG msg;
    g_hHook = NULL;

    const int RUN_MS = 10000; // 设定运行10000毫秒(10秒)

    g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, kbHook, NULL, 0);
    if (g_hHook == NULL)
    {
        printf("HOOK FAILED");
        return 1;
    }

    // 设置定时器,RUN_MS毫秒后发送WM_TIMER消息
    SetTimer(NULL, 1, RUN_MS, NULL);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.message == WM_TIMER)
        {
            // 收到定时器消息,先销毁定时器再退出循环
            KillTimer(NULL, 1);
            break;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(g_hHook);
    printf("Key logs saved to: %s", path);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:15:54