![](/img/trans.png)
[英]Windows 10 virtual COM port - ReadFile stops working after some period of time
[英]SetWindowsHook stops working after some time
我在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;
}
您是否检查了钩子是否在不再被调用时仍在安装(即检查BOOL UnhookWindowsHook的返回值)?
可能安装了另一个不保留您的钩子的钩子,而不调用CallNextHookEx()。
尝试改用WH_MOUSE_LL
。
编辑:关于LowLevelMouseProc函数
挂钩过程处理消息的时间应少于以下注册表项中LowLevelHooksTimeout值中指定的数据条目的时间:
HKEY_CURRENT_USER\\Control Panel\\Desktop
该值以毫秒为单位。 如果挂钩过程在此间隔内未返回,则系统会将消息传递到下一个挂钩。
我假设挂钩函数是在DLL中实现的? 也许某些事情减少了该DLL上的引用计数,所以Windows卸载了它,从而停止了挂接功能。
我建议您在DLL中进行的第一件事是自己调用LoadLibrary ,以便使包含钩子函数的DLL的引用计数增加一个。 确保不要调用FreeLibrary来测试该理论。
您应该关闭句柄。
我能想到的唯一会导致崩溃的事情是,如果您的钩形手柄已损坏。 您可以捕获异常吗? 您是否尝试过打破异常以在发生异常时打破? 如果您不知道发生了什么异常,是否尝试过在代码周围添加__try / __ finally块?
挂钩中的基本数据是否在共享段中? 至少是接收通知消息的目标窗口的HHOOK和HWND。
来晚了,但是我也遇到了同样的问题,并通过创建一个新的线程来执行任务并尽快从过程返回来解决了这个问题。 希望这对某人有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.