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

ところで、フックハンドルをCloseHandleする必要があります。

私が考えることができる唯一のクラッシュの原因は、フックハンドルが破壊された場合です。例外をトラップできますか? 発生している例外が発生したときにブレークするために、例外でブレークしようとしましたか? 発生している例外がわからない場合は、コードの周りに __try/__finally ブロックを追加してみましたか?

于 2009-10-08T21:24:50.783 に答える
1

フック関数は DLL で実装されていると思いますか? おそらく何かがその DLL の参照カウントを減らしたため、Windows がそれをアンロードし、フック関数が停止します。

フック関数を含む DLL の参照カウントが 1 つ増えるように、DLL 内で最初に自分でLoadLibraryを呼び出すことをお勧めします。この理論をテストするためにFreeLibraryを呼び出さないようにしてください。

于 2009-10-07T16:32:37.657 に答える
0

共有セグメントのフックに不可欠なデータはありますか?少なくとも、これは通知メッセージを受信するターゲットウィンドウのHHOOKとHWNDになります。

于 2009-09-23T10:30:28.997 に答える