C# 钩子知识

来源:互联网 发布:微信公众源码 编辑:程序博客网 时间:2024/05/16 19:54
要实现系统钩子其实很简单,调用三个Win32的API即可。SetWindowsHookEx 用于设置钩子。(设立一道卡子,盘查需要的信息) [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )] public static extern IntPtr SetWindowsHookEx ( WH_Codes idHook, HookProc lpfn, IntPtr pInstance, int threadId );CallNextHookEx 用于传递钩子(消息是重要的,所以从哪里来,就应该回到哪里去,除非你决定要封锁消息) [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )] public static extern int CallNextHookEx ( IntPtr pHookHandle, int nCode, Int32 wParam, IntPtr lParam );UnhookWindowsHookEx 卸载钩子(卸载很重要,卡子设多了会造成拥堵) [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )] public static extern bool UnhookWindowsHookEx ( IntPtr pHookHandle );////////////////////////////////////////////////////////////////////////////////1、安装钩子:   SetWindowsHookEx 函数原形:HHOOK SetWindowsHookEx( int idHook, // 钩子类型, HOOKPROC lpfn, // 钩子函数地址 INSTANCE hMod, // 钩子所在的实例的句柄, DWORD dwThreadId // 钩子所监视的线程的线程号 ) hMod: 对于线程序钩子,参数传NULL; 对于系统钩子:参数为钩子DLL的句柄  dwThreadId:对于全局钩子,该参数为NULL。 钩子类型用WH_CALLWNDPROC=4(发送到窗口的消息。由SendMessage触发) 返回:成功:返回SetWindowsHookEx返回所安装的钩子句柄; 失败:NULL;2、回调,你要截获消息就在这里进行:LRESULT WINAPI MyHookProc( int nCode , // 指定是否需要处理该消息 WPARAM wParam, // 包含该消息的附加消息 LPARAM lParam // 包含该消息的附加消息 )3、调用下一个钩子LRESULT CallNextHookEx( HHOOK hhk, // 是您自己的钩子函数的句柄。用该句柄可以遍历钩子链 int nCode, // 把传入的参数简单传给CallNextHookEx即可 WPARAM wParam, // 把传入的参数简单传给CallNextHookEx即可 LPARAM lParam // 把传入的参数简单传给CallNextHookEx即可 );4、用完后记得卸载钩子哦,要不然你的系统会变得奇慢无比!BOOL UnhookWindowsHookEx( HHOOK hhk // 要卸载的钩子句柄。 )把上面这些API用C#封装一下,就可以直接用了!给个线程钩子的例子吧(两个Form都在同一个线程中运行):using System.Runtime.InteropServices;public class Form1 : System.Windows.Forms.Form{ ... //定义委托(钩子函数,用于回调) public delegate int HookProc(int code, IntPtr wparam, ref CWPSTRUCT cwp); //安装钩子的函数 [DllImport("User32.dll",CharSet = CharSet.Auto)] public static extern IntPtr SetWindowsHookEx(int type, HookProc hook, IntPtr instance, int threadID); //调用下一个钩子的函数 [DllImport("User32.dll",CharSet = CharSet.Auto)] public static extern int CallNextHookEx(IntPtr hookHandle, int code, IntPtr wparam, ref CWPSTRUCT cwp); //卸载钩子 [DllImport("User32.dll",CharSet = CharSet.Auto)] public static extern bool UnhookWindowsHookEx(IntPtr hookHandle); //获取窗体线程ID DllImport("User32.dll",CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, int ID); private HookProc hookProc; private IntPtr hookHandle = IntPtr.Zero; public Form1() { .... //挂接钩子处理方法 this.hookProc = new HookProc(myhookproc); } //开始拦截private bool StartHook() { Form2 f=new Form2(); f.Show();//加上这个 //安装钩子,拦截系统向Form2发出的消息 this.hookHandle = SetWindowsHookEx(4, hookProc, IntPtr.Zero ,GetWindowThreadProcessId(f.Handle,0)); return (this.hookHandle != 0); } //停止拦截 private bool StopHook() { return UnhookWindowsHookEx(this.hookHandle); } //钩子处理函数,在这里拦截消息并做处理 private int myhookproc(int code, IntPtr wparam, ref CWPSTRUCT cwp) { switch(code) { case 0: switch(cwp.message) { case 0x0000F://WM_PAINT,拦截WM_PAINT消息 //do something break; } break; } return CallNextHookEx(hookHandle,code,wparam, ref cwp); } [StructLayout(LayoutKind.Sequential)] public struct CWPSTRUCT { public IntPtr lparam; public IntPtr wparam; public int message; public IntPtr hwnd; }}public class Form2 : System.Windows.Forms.Form{ ....}
原创粉丝点击