一段时间后,SetWindowsHookex停止工作

时间:2009-09-23 10:09:10

标签: c++ windows winapi mouse-hook

我在WM_MOUSE上定义了一个全局挂钩,它在一段时间内完美运行。每次鼠标移动时,它都会向特定窗口发布消息。

在一段随机时间之后,挂钩停止发送消息。如果我取消注册并注册挂钩它再次工作。我想在Windows中发生的一些具体事情导致挂钩停止,但我找不到。

有什么想法吗?

编辑:当挂钩不再处于活动状态时,我将调试器附加到其他进程,我发现dll不再被加载。

什么可能导致钩子dll卸载?

Edit2 :我发现MouseHookProc中的崩溃任何进程中的dll都会从它加载的每个进程中卸载hook dll。我无法找到导致代码崩溃的原因。可能是一些竞争条件或什么?这是hook dll代码:

#include "stdafx.h"

// define a data segment
#pragma data_seg(".SHARED")
HWND  hwnd=0;
HHOOK hHook=0;
#pragma data_seg()

// tell the linker to share the segment
#pragma comment(linker, "/section:.SHARED,RWS")

#define WM_MOUSEHOOK            WM_USER+0x100

HINSTANCE hInstance=0;


// this allow to build a very small executable without any extra libraries
// (probably not the problem, the bug still occurs without this )
#ifndef _DEBUG
void *__cdecl operator new(unsigned int bytes)
{
    return HeapAlloc(GetProcessHeap(), 0, bytes);
}

void __cdecl operator delete(void *ptr)
{
    if(ptr) HeapFree(GetProcessHeap(), 0, ptr);
}

extern "C" int __cdecl __purecall(void)
{
    return 0;
}
#endif

BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{    
    hInstance=hModule;
    return TRUE;
}

LRESULT CALLBACK MouseHookProc(int nCode, WORD wParam, DWORD lParam)
{
    if(nCode==HC_ACTION && (wParam==WM_MOUSEMOVE || wParam==WM_NCMOUSEMOVE))
    {            
        MSLLHOOKSTRUCT *mhs=(MSLLHOOKSTRUCT*)lParam;        
        PostMessage(hwnd, WM_MOUSEHOOK, wParam, 0);
    }
    return CallNextHookEx(hHook,nCode,wParam,lParam);
}

extern "C" __declspec(dllexport) HHOOK InitializeWindowsHook(char *title)
{
    hwnd=FindWindow(0, title);
    if(hwnd)
        hHook=SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, hInstance, 0);
    return hHook;
}

extern "C" __declspec(dllexport) BOOL DeinitializeWindowsHook()
{
    if(hHook) {
        BOOL b=UnhookWindowsHookEx(hHook);
        hHook=0;
        return b;
    }
    return FALSE;
}

6 个答案:

答案 0 :(得分:3)

你有没有检查过钩子是否还没有被调用(即检查BOOL UnhookWindowsHook的返回值)?

可能安装了另一个不保留挂钩的挂钩,而不是调用CallNextHookEx()。

答案 1 :(得分:1)

请尝试使用WH_MOUSE_LL

编辑关于LowLevelMouseProc Function

  

钩子程序应该处理一个   消息的时间比数据少   条目中指定的条目   LowLevelHooksTimeout中的值   以下注册表项:

     

HKEY_CURRENT_USER\Control Panel\Desktop

     

该值以毫秒为单位。如果   钩子程序不会返回   这个间隔,系统将通过   消息到下一个钩子。

答案 2 :(得分:1)

我假设钩子函数是在DLL中实现的?也许某些东西减少了该DLL的引用计数,因此Windows卸载它,这会停止你的钩子函数。

我建议您在DLL中执行的第一件事就是自己调用LoadLibrary,以便包含钩子函数的DLL的引用计数增加1。请务必不要致电FreeLibrary来测试这个理论。

答案 3 :(得分:1)

你应该关闭钩手柄btw。

我能想到的唯一可能导致崩溃的是你的钩子手柄被破坏了。你能抓住这个例外吗?您是否尝试过中断异常以在发生异常时中断?如果您不知道发生了什么异常,您是否尝试在代码周围添加__try / __ finally块?

答案 4 :(得分:0)

共享细分中钩子的基本数据是什么?这至少是HHOOK和接收通知消息的目标窗口的HWND。

答案 5 :(得分:0)

迟到了派对,但我也面临同样的问题,并通过创建一个新的线程来执行我的任务并尽快从程序返回来解决。希望这有助于某人。