c# 鉤子學(xué)習(xí)筆記
更新時(shí)間:2011年04月16日 18:31:12 作者:
今天弄了一下c#的鉤子,沒弄好,但是鉤子安裝成功,可以捕獲鍵盤事件。
包括系統(tǒng)鉤子和線程鉤子,或者叫全局鉤子和私有鉤子。系統(tǒng)鉤子需要一個(gè)單獨(dú)的DLL,這個(gè)地方耽誤了不少時(shí)間,網(wǎng)上有說可以不用單獨(dú)DLL的。
現(xiàn)在開始貼代碼,代碼參照了紅黑聯(lián)盟中的一篇文章。
public class SetHook
{
public class HookTypes
{
/// <summary>
/// 鉤子類型
/// </summary>
public enum HookType
{
WH_JOURNALRECORD = 0,//對(duì)寄送至消息隊(duì)列的輸入消息進(jìn)行記錄
WH_GETMESSAGE = 3,//對(duì)寄送至消息隊(duì)列的消息進(jìn)行監(jiān)視
WH_JOURNALPLAYBACK = 1,//對(duì)此前由WH_JOURNALRECORD 掛鉤處理過程紀(jì)錄的消息進(jìn)行寄送
WH_CALLWNDPROC = 4,//在系統(tǒng)將消息發(fā)送至目標(biāo)窗口處理過程之前,對(duì)該消息進(jìn)行監(jiān)視
WH_CBT = 5,//接受對(duì)CBT應(yīng)用程序有用的消息
WH_MSGFILTER = -1,//監(jiān)視由對(duì)話框、消息框、菜單條、或滾動(dòng)條中的輸入事件引發(fā)的消息
WH_SYSMSGFILTER = 6,//監(jiān)視由對(duì)話框,消息框,菜單條,滾動(dòng)條中的輸入事件引發(fā)的消息
//8
WH_DEBUG = 9,//對(duì)其他鉤子處理過程進(jìn)行調(diào)試
WH_SHELL = 10,//接受對(duì)外殼應(yīng)用程序有用的通知
WH_FOREGROUNDIDLE = 11,//當(dāng)應(yīng)用程序的前臺(tái)線程即將進(jìn)入空閑狀態(tài)時(shí)被調(diào)用,它有助于在空閑時(shí)間內(nèi)執(zhí)行低優(yōu)先級(jí)的任務(wù)
#region 鼠標(biāo)和鍵盤事件
/// <summary>
/// 對(duì)擊鍵消息進(jìn)行監(jiān)視
/// </summary>
WH_KEYBOARD = 2,
/// <summary>
/// 只能在windows NT中被安裝,用來對(duì)底層的鍵盤輸入事件進(jìn)行監(jiān)視
/// </summary>
WH_KEYBOARD_LL = 13,
/// <summary>
/// 對(duì)鼠標(biāo)消息進(jìn)行監(jiān)視
/// </summary>
WH_MOUSE = 7,
/// <summary>
/// 只能在windows NT中被安裝,用來對(duì)底層鼠標(biāo)事件進(jìn)行監(jiān)視
/// </summary>
WH_MOUSE_LL = 14,
#endregion
}
}
public abstract class Hooks : HookTypes
{
public delegate int HookProc(int nCode, int wParam, IntPtr IParam);
/// <summary>
/// 安裝鉤子
/// </summary>
/// <param name="idHook">鉤子類型,即它處理的消息類型</param>
/// <param name="lpfn"> 鉤子函數(shù)地址</param>
/// <param name="hInstance">應(yīng)用程序?qū)嵗木浔?。?biāo)識(shí)包含lpfn所指的子程的DLL</param>
/// <param name="threadId">安裝鉤子后想監(jiān)控的線程的ID號(hào), 如果為0,鉤子子程與所有的線程關(guān)聯(lián),即為全局鉤子</param>
/// <returns>返回參數(shù)為鉤子句柄,失敗為NULL</returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(HookType hooktype, HookProc lpfn, IntPtr hInstance, int threadId);
/// <summary>
/// 卸載鉤子
/// </summary>
/// <param name="idHook">要卸載的鉤子句柄</param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
/// <summary>
/// 繼續(xù)下一個(gè)鉤子
/// </summary>
/// <param name="idHook"></param>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="IParam"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr IParam);
/// <summary>
/// 獲取當(dāng)前線程編號(hào)
/// </summary>
/// <returns></returns>
[DllImport("kernel32")]
public static extern int GetCurrentThreadId();
#region
/// <summary>
/// 委托對(duì)象
/// </summary>
public HookProc proc;
public abstract int SetWindowsHookEx();
#endregion
}
public class AddHook : Hooks
{
HookType hooktyp;
HookProc hookproc;
public AddHook(HookType _hooktype, HookProc _hookproc)
{
this.hooktyp = _hooktype;
this.hookproc = _hookproc;
}
public int AddPrivateHook()
{
return SetWindowsHookEx();
}
/// <summary>
/// 線程鉤子
/// </summary>
/// <returns></returns>
public override int SetWindowsHookEx()
{
//int theadId = System.Threading.Thread.CurrentThread.ManagedThreadId(); 應(yīng)對(duì)GetCurrentThreadId()的過時(shí)
int hookId = 0;
object hookId_ = SetWindowsHookEx(this.hooktyp, this.hookproc, IntPtr.Zero, GetCurrentThreadId());
if (hookId_ != null)
{
hookId = (int)hookId_;
}
return hookId;
}
//系統(tǒng)鉤子和這差不多,安裝鉤子的時(shí)候后兩個(gè)參數(shù)不一樣
}
}
調(diào)用我新建了一個(gè)類,方便調(diào)用線程或者系統(tǒng)鉤子,這里就不貼了
現(xiàn)在開始貼代碼,代碼參照了紅黑聯(lián)盟中的一篇文章。
復(fù)制代碼 代碼如下:
public class SetHook
{
public class HookTypes
{
/// <summary>
/// 鉤子類型
/// </summary>
public enum HookType
{
WH_JOURNALRECORD = 0,//對(duì)寄送至消息隊(duì)列的輸入消息進(jìn)行記錄
WH_GETMESSAGE = 3,//對(duì)寄送至消息隊(duì)列的消息進(jìn)行監(jiān)視
WH_JOURNALPLAYBACK = 1,//對(duì)此前由WH_JOURNALRECORD 掛鉤處理過程紀(jì)錄的消息進(jìn)行寄送
WH_CALLWNDPROC = 4,//在系統(tǒng)將消息發(fā)送至目標(biāo)窗口處理過程之前,對(duì)該消息進(jìn)行監(jiān)視
WH_CBT = 5,//接受對(duì)CBT應(yīng)用程序有用的消息
WH_MSGFILTER = -1,//監(jiān)視由對(duì)話框、消息框、菜單條、或滾動(dòng)條中的輸入事件引發(fā)的消息
WH_SYSMSGFILTER = 6,//監(jiān)視由對(duì)話框,消息框,菜單條,滾動(dòng)條中的輸入事件引發(fā)的消息
//8
WH_DEBUG = 9,//對(duì)其他鉤子處理過程進(jìn)行調(diào)試
WH_SHELL = 10,//接受對(duì)外殼應(yīng)用程序有用的通知
WH_FOREGROUNDIDLE = 11,//當(dāng)應(yīng)用程序的前臺(tái)線程即將進(jìn)入空閑狀態(tài)時(shí)被調(diào)用,它有助于在空閑時(shí)間內(nèi)執(zhí)行低優(yōu)先級(jí)的任務(wù)
#region 鼠標(biāo)和鍵盤事件
/// <summary>
/// 對(duì)擊鍵消息進(jìn)行監(jiān)視
/// </summary>
WH_KEYBOARD = 2,
/// <summary>
/// 只能在windows NT中被安裝,用來對(duì)底層的鍵盤輸入事件進(jìn)行監(jiān)視
/// </summary>
WH_KEYBOARD_LL = 13,
/// <summary>
/// 對(duì)鼠標(biāo)消息進(jìn)行監(jiān)視
/// </summary>
WH_MOUSE = 7,
/// <summary>
/// 只能在windows NT中被安裝,用來對(duì)底層鼠標(biāo)事件進(jìn)行監(jiān)視
/// </summary>
WH_MOUSE_LL = 14,
#endregion
}
}
public abstract class Hooks : HookTypes
{
public delegate int HookProc(int nCode, int wParam, IntPtr IParam);
/// <summary>
/// 安裝鉤子
/// </summary>
/// <param name="idHook">鉤子類型,即它處理的消息類型</param>
/// <param name="lpfn"> 鉤子函數(shù)地址</param>
/// <param name="hInstance">應(yīng)用程序?qū)嵗木浔?。?biāo)識(shí)包含lpfn所指的子程的DLL</param>
/// <param name="threadId">安裝鉤子后想監(jiān)控的線程的ID號(hào), 如果為0,鉤子子程與所有的線程關(guān)聯(lián),即為全局鉤子</param>
/// <returns>返回參數(shù)為鉤子句柄,失敗為NULL</returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(HookType hooktype, HookProc lpfn, IntPtr hInstance, int threadId);
/// <summary>
/// 卸載鉤子
/// </summary>
/// <param name="idHook">要卸載的鉤子句柄</param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
/// <summary>
/// 繼續(xù)下一個(gè)鉤子
/// </summary>
/// <param name="idHook"></param>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="IParam"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr IParam);
/// <summary>
/// 獲取當(dāng)前線程編號(hào)
/// </summary>
/// <returns></returns>
[DllImport("kernel32")]
public static extern int GetCurrentThreadId();
#region
/// <summary>
/// 委托對(duì)象
/// </summary>
public HookProc proc;
public abstract int SetWindowsHookEx();
#endregion
}
public class AddHook : Hooks
{
HookType hooktyp;
HookProc hookproc;
public AddHook(HookType _hooktype, HookProc _hookproc)
{
this.hooktyp = _hooktype;
this.hookproc = _hookproc;
}
public int AddPrivateHook()
{
return SetWindowsHookEx();
}
/// <summary>
/// 線程鉤子
/// </summary>
/// <returns></returns>
public override int SetWindowsHookEx()
{
//int theadId = System.Threading.Thread.CurrentThread.ManagedThreadId(); 應(yīng)對(duì)GetCurrentThreadId()的過時(shí)
int hookId = 0;
object hookId_ = SetWindowsHookEx(this.hooktyp, this.hookproc, IntPtr.Zero, GetCurrentThreadId());
if (hookId_ != null)
{
hookId = (int)hookId_;
}
return hookId;
}
//系統(tǒng)鉤子和這差不多,安裝鉤子的時(shí)候后兩個(gè)參數(shù)不一樣
}
}
調(diào)用我新建了一個(gè)類,方便調(diào)用線程或者系統(tǒng)鉤子,這里就不貼了
您可能感興趣的文章:
- C#使用鉤子獲得按鍵信息的方法
- C#實(shí)現(xiàn)的鼠標(biāo)鉤子
- C#鍵盤鼠標(biāo)鉤子實(shí)例
- 基于C#實(shí)現(xiàn)的HOOK鍵盤鉤子實(shí)例代碼
- C# Hook鉤子實(shí)例代碼 截取鍵盤輸入
- C# WinForm捕獲未處理的異常實(shí)例解析
- C# Winform實(shí)現(xiàn)捕獲窗體最小化、最大化、關(guān)閉按鈕事件的方法
- C#通過接口與線程通信(捕獲線程狀態(tài))示例代碼
- C# WinForm捕獲全局變量異常 SamWang解決方法
- C#實(shí)現(xiàn)可捕獲幾乎所有鍵盤鼠標(biāo)事件的鉤子類完整實(shí)例
相關(guān)文章
Unity實(shí)現(xiàn)高效的音效管理類的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何通過Unity實(shí)現(xiàn)高效的音效管理類,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下2023-03-03C#?使用?Filestream?修改大文件指定位置數(shù)據(jù)
這篇文章主要介紹了C#?使用?Filestream修改大文件指定位置數(shù)據(jù),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09C#實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載的方法
這篇文章主要介紹了C#實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載的方法,涉及網(wǎng)絡(luò)文件操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法
這篇文章主要介紹了C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法,涉及C#針對(duì)數(shù)組的遍歷、校驗(yàn)及排序等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08C#中Decimal類型截取保留N位小數(shù)并且不進(jìn)行四舍五入操作
這篇文章主要介紹了C#中Decimal類型截取保留N位小數(shù)并且不進(jìn)行四舍五入操作,本文給出需求說明和實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06c#標(biāo)準(zhǔn)idispose模式使用示例
下面將把C#里實(shí)現(xiàn)IDispose模式的代碼展現(xiàn)出來,大家一起來學(xué)習(xí)一下,它的使用場(chǎng)合也很多的,當(dāng)我們手動(dòng)對(duì)網(wǎng)站,數(shù)據(jù)庫(kù)作封裝時(shí),都會(huì)用的到2014-02-02C#使用WebSocket實(shí)現(xiàn)聊天室功能
這篇文章主要為大家詳細(xì)介紹了C#使用WebSocket實(shí)現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02