看了很多資料,都提到系統(tǒng)鉤子(Hook)必須是一個dll,這樣Windows才能在所有進(jìn)程中共享鉤子代碼。 與鉤子相關(guān)的3個Windows API函數(shù)是: SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx,它們的簡要說明如下: ![]() ![]() ![]() ![]() ![]() ![]() idHook -- 系統(tǒng)鉤子類型,實(shí)際上是一個int值,具體的定義請看MSDN lpfn -- 鉤子回調(diào)函數(shù)指針,當(dāng)收到鉤子消息時就執(zhí)行這個回調(diào)函數(shù),回調(diào)函數(shù)有3個參數(shù),不同類型的鉤子這3個參數(shù)有不同的含義,具體請看MSDN。 hMod -- DLL實(shí)例句柄(我猜是這樣,我不熟悉Win32API編程),當(dāng)鉤子為系統(tǒng)鉤子時這個參數(shù)是必須的,如果是單個程序或者線程使用的鉤子那么可以不用這個值。 dwThreadId -- 線程ID,如果是單個程序或者線程使用的鉤子這個參數(shù)是必須的。 SetWindowsHookEx返回所設(shè)置的鉤子的句柄。 BOOL UnhookWindowsHookEx(HHOOK hhk); hhk -- 所要注銷的鉤子的句柄 UnhookWindowsHookEx返回注銷鉤子是否成功。
![]() ![]() ![]() ![]() ![]() hhk -- 起始鉤子句柄,如果是在鉤子回調(diào)函數(shù)中調(diào)用CallNextHookEx時傳的通常是本鉤子句柄。 nCode -- 鉤子回調(diào)函數(shù)參數(shù)1,具體含義視鉤子類型而定。 wParam -- 鉤子回調(diào)函數(shù)參數(shù)2,具體含義視鉤子類型而定。 lParam -- 鉤子回調(diào)函數(shù)參數(shù)3,具體含義視鉤子類型而定。 從以上3個函數(shù)的簡要說明可以看出所用到的參數(shù)幾乎都是簡單的參數(shù),稍微復(fù)雜就是回調(diào)函數(shù)(在C#中用delegate類型來實(shí)現(xiàn),后面會提到),但是最讓人頭疼的就是DLL的實(shí)例句柄,C#制作的DLL并不像C做的DLL有DllMain入口可以接受到DLL實(shí)例句柄。 我目前唯一的辦法就是使用C做一個系統(tǒng)鉤子DLL再讓C#調(diào)用。底下是DLL的代碼。 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 然后在C#項目中創(chuàng)建一個系統(tǒng)鉤子類,提供創(chuàng)建鉤子和注銷鉤子的接口,代碼如下 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 上面用到的User32.HookProc類型不是.NET框架提供的,是自己定義的一個委托類型,聲明如下 ![]() 現(xiàn)在你的C#程序就可以使用各種系統(tǒng)鉤子了,我們目前已經(jīng)使用的有低級別鼠標(biāo)鉤子和低級別鍵盤鉤子。 應(yīng)用低級別鼠標(biāo)鉤子時會遇到這樣一個問題: 低級別鼠標(biāo)鉤子的回調(diào)函數(shù)lParam是一個MSLLHOOKSTRUCT結(jié)構(gòu)體指針,C#中怎么獲取這個結(jié)構(gòu)體的實(shí)例呢?實(shí)現(xiàn)代碼如下 ![]() ![]() ![]() ![]() ![]() 通過聲明非安全代碼來獲取指針?biāo)笇ο蟆? MSLLHOOKSTRUCT結(jié)構(gòu)體的C#定義如下: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
|