用 2017 工具链编译, 创建线程这一步就卡住不运行了:
换 2019 编译,线程运行正常,钩子成功注册:
C++代码:
#include <Windows.h> #include <stdio.h> #include <thread> extern "C" { __declspec(dllexport) BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved) // reserved { // Perform actions based on the reason for calling. switch (fdwReason) { case DLL_PROCESS_ATTACH: { // Initialize once for each new process. // Return FALSE to fail DLL load. printf("附加到进程\n"); std::thread th([]{ HHOOK hook = SetWindowsHookExW(WH_KEYBOARD_LL, (HOOKPROC)[](int code, WPARAM wParam, LPARAM lParam)->LRESULT{ KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; // Do the wParam and lParam parameters contain information about a keyboard message. if (code == HC_ACTION) { // Messsage data is ready for pickup if (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN) { if (p->vkCode == VK_LWIN) { printf("拦截 KeyDown 事件\n"); return TRUE; } } } // hook procedure must pass the message *Always* return CallNextHookEx(NULL, code, wParam, lParam); }, NULL, 0); printf("hook = %p\n", hook); MSG msg = {0}; while (1) { GetMessage(&msg, NULL, 0, 0); TranslateMessage(&msg); DispatchMessage(&msg); } }); th.detach(); break; } case DLL_THREAD_ATTACH: // Do thread-specific initialization. printf("附加到线程\n"); break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. printf("从线程分离\n"); break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. printf("从进程分离\n"); break; } return TRUE; // Successful DLL_PROCESS_ATACH. } } 

