VS2019 可以在 DllMain 里面创建线程, VS2017 则会被一直挂起?

2022-03-11 15:51:01 +08:00
 Kasumi20

用 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_ATTACH.
    }
}
1541 次点击
所在节点    C++
5 条回复
x1596357
2022-03-11 15:54:02 +08:00
Kasumi20
2022-03-11 15:58:22 +08:00
@x1596357 那为什么换 2019 编译又可以运行呢
codehz
2022-03-11 16:03:04 +08:00
@Kasumi20 没必要研究这种巧合(
基于巧合写代码的结果就是一个不小心就被破坏了
ysc3839
2022-03-11 16:44:11 +08:00
感觉是 X-Y Problem https://coolshell.cn/articles/10804.html
看上去你是注入 DLL 之后再设置一个 low level keyboard hook ?为什么要这么做?直接在另一个进程中跑不行吗?
yulon
2022-03-11 16:48:47 +08:00
首先 DllMain 里不推荐创建线程,如果真要创建线程请用 CreateThread ,用 std::thread 和 _beginthread 都有可能死锁,因为要初始化语言标准库。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/839696

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX