5

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

随机时间后,钩子停止发送消息。如果我取消注册并注册钩子,它会再次工作。我想在 Windows 中发生的某些特定事情会导致钩子停止,但我找不到什么。

有任何想法吗 ?

编辑:当钩子不再活动时,我将调试器附加到其他进程,并且我观察到不再加载 dll。

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

Edit2:我发现 MouseHookProc 中的崩溃,任何进程中的 dll 从它加载的每个进程中卸载钩子 dll。我找不到导致代码崩溃的原因。可能是一些比赛条件或什么?这是钩子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;
}
4

6 回答 6

3

您是否检查过,当不再调用钩子时是否仍然安装了钩子(即检查 BOOL UnhookWindowsHook 的返回值)?

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

于 2009-10-07T12:47:52.800 回答
1

尝试WH_MOUSE_LL改用。

编辑:关于LowLevelMouseProc 函数

挂钩过程应在比以下注册表项中的 LowLevelHooksTimeout 值中指定的数据条目更短的时间内处理消息:

HKEY_CURRENT_USER\Control Panel\Desktop

该值以毫秒为单位。如果在此时间间隔内钩子程序没有返回,系统会将消息传递给下一个钩子。

于 2009-09-23T10:30:51.510 回答
1

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

我建议你在你的DLL中做的第一件事是自己调用LoadLibrary,这样包含钩子函数的DLL的引用计数就会增加一个。确保不要调用FreeLibrary来测试这个理论。

于 2009-10-07T16:32:37.657 回答
1

顺便说一句,你应该 CloseHandle 你的钩子句柄。

我能想到的唯一会导致崩溃的是,如果您的挂钩手柄已被破坏。你能捕获异常吗?您是否尝试过在发生异常时中断异常?如果您不知道发生了什么异常,您是否尝试在代码周围添加 __try/__finally 块?

于 2009-10-08T21:24:50.783 回答
0

您的钩子的基本数据是否在共享段中?这至少是接收通知消息的目标窗口的 HHOOK 和 HWND。

于 2009-09-23T10:30:28.997 回答
0

聚会迟到了,但我也遇到了同样的问题,并通过创建一个新线程来执行我的任务并尽快从程序返回来解决。希望这可以帮助某人。

于 2016-03-30T05:10:59.557 回答