鉤子函式聲明
C#是.NET Framework平台的相伴語言,用它本身的類庫和編譯器提供的方法是無法實現全局鉤子的。但實際上對於非託管代碼的調用在C#中是成立的,鉤子函式存在於user32.dll中,使用DllImport屬性可以引用非託管代碼類庫中的方法。
首先是鉤子函式的安裝:
[DllImport("user32.dll")]
public static extern int SetWindowsHookEx(
int idHook, //鉤子的類型,即它處理的訊息類型,可以用整型變數表示
HookProc lpfn, //鉤子發揮作用時的委託類型的回調函式(當鉤子得到系統訊息時調用這個函式)
IntPtr hInstance, //應用程式實例的模組句柄 (要設定鉤子的應用程式的句柄)
int threadId //與安裝的鉤子子程相關聯的執行緒的標識符(如果為0即為全局鉤子)
);
調用下一個鉤子:
[DllImport("user32.dll")]
public static extern int CallNextHookEx(
int idHook, //當前的鉤子的類型,由SetWindowsHookEx函式返回
int nCode,//傳給鉤子過程的事件代碼
wParam,//傳給鉤子子程的值,其具體含義與鉤子類型有關
lParam //傳給鉤子子程的值,其具體含義與鉤子類型有關
);
卸載鉤子:
[DllImport("user32.dll")]
public static extern bool UnhookWindowsHookEx(
int idHook //鉤子的類型
);
鉤子函式使用
首先聲明一個委託:
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
然後是委託指向的函式:
private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) //鉤子子程
{
//當鉤子得到訊息是執行這裡的語句
//return 1 時代表將訊息禁止攔截
//當return 0 或CallNextHookEx() 時代表不攔截次訊息的執行
}
開始安裝鉤子:
static int hHook = 0;
HookProc KeyboardHookProcedure;
public void Hook_Start() // 定義一個用來安裝鉤子的方法
{
if (hHook == 0)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);//給委託變數賦初值
hHook = SetWindowsHookEx(
13, //此鉤子的類型為全局鍵盤鉤子 (14表示全局滑鼠鉤子)
KeyboardHookProcedure,//鉤子子程(委託變數)
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),//表示全局鉤子
0 //表示全局鉤子
);
}
else //卸載鍵盤鉤子
{
UnhookWindowsHookEx(hHook); // 卸載鉤子
hHook = 0;
}
}
上面的方法中用到了"GetModuleHandle"這個方法需要引用格式為:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName)
如果這個參數是一個指定進程的句柄就說明這是一個局部鉤子。
最後
接下來就可以調用這個方法來創建一個鉤子進程了
代碼寫在KeyboardHookProc 也就是鉤子子程里就可以執行了
比如你可以直接寫上 return 1; 這樣就把所有的鍵盤訊息都禁止不執行了
也可以把SetWindowsHookEx 中的鉤子類型改為14(全局滑鼠鉤子)讓滑鼠失靈