代码之家  ›  专栏  ›  技术社区  ›  Gishu

如何添加系统“windows挂钩”,以便在创建/激活windows时收到通知?

  •  5
  • Gishu  · 技术社区  · 15 年前

    尝试使用开放库 http://mwinapi.sourceforge.net/ 第一尽管它可以很好地作为一个OO层来枚举窗口和其他东西。它做不好

    Dino E.'s post on Windows Hooks in the .Net framework

    我的目的是让这个应用程序运行,并让它能够在运行时记录所有创建的窗口 . 召唤所有的眼球。。。

    can't write global windows hooks in .Net

    于是我切换到C++。尽管如此,所有WinAPI调用都返回有效句柄,但我没有看到我的筛选函数被调用——似乎没有收到任何通知。还是不行。。。有人能发现错误吗。

    void CWinHookFacade::Hook()
    {
        HMODULE hCurrentDll = LoadLibrary(_T("[Path to my hook dll]"));
        m_HookHandle = SetWindowsHookEx(WH_CBT, 
            FilterFunctionForHook, 
            hCurrentDll, 
            0);
        if (m_HookHandle == NULL)
        {
            throw new std::exception("Unable to hook");
        }
    
    }
    void CWinHookFacade::Unhook()
    {
        if (!UnhookWindowsHookEx(m_HookHandle))
        {
            throw new std::exception("Unhook failed!");
        }
        m_HookHandle = NULL;
    }
    
    LRESULT CWinHookFacade::FilterFunctionForHook(int code, WPARAM wParam, LPARAM lParam)
    {
        if (code >= 0)
        {
            switch(code)
            {
            case HCBT_CREATEWND:
                wprintf(_T("Created Window"));
                break;
            case HCBT_ACTIVATE:
                wprintf(_T("Activated Window"));
                break;
            case HCBT_DESTROYWND:
                wprintf(_T("Destroy Window"));
                break;
            }
        }
    
        return CallNextHookEx(m_HookHandle, code, wParam, lParam);
    }
    

    Client exe像这样调用Hook\u DLL

    int _tmain(int argc, _TCHAR* argv[])
    {
        CWinHookFacade::Hook();
        getchar();
        CWinHookFacade::Unhook();
    }
    
    2 回复  |  直到 15 年前
        1
  •  7
  •   Andy    15 年前

    我认为您遇到的问题是因为您试图在C#中实现一个钩子函数。基于 pinvoke.net's documentation 在…上 SetWindowsHookEx()

    最好的方法是将此代码移到非托管C++ DLL,并使用某种进程间通信将钩子过程截获的数据发送回应用程序。

    使现代化

    LoadLibrary() 得到 HINSTANCE 你的动态链接库?打电话可能会更好 GetModuleHandle() 因为您的DLL已经加载。

    至于为什么你的钩子程序从未被调用,你是如何验证的?由于您要挂接系统中的所有GUI线程,这意味着您的DLL需要加载到所有GUI进程中。你很可能看不到打电话的结果 wprintf() 因为其他进程没有向上显示输出的控制台窗口。

    Process Explorer )。您可以使用“查找|查找句柄”或“DLL”菜单项来搜索DLL的名称-它应在所有进程中显示,并带有消息循环。

    wprintf() OutputDebugString() 并运行一个实用程序,如 DebugView

    m_HookHandle 变量在那里无效。你应该把它储存在一个容器里 shared data segment 这样,DLL的所有加载实例都将具有相同的值。

        2
  •  5
  •   Gishu    15 年前

    blog post 以防将来有人需要。