最近在写一个采集程序
需要用到钩子
为了学习钩子 特写了个小demo
为实现高级功能的钩子打好基础
下面是代码
----------------
钩子类型
1 namespace CSharpHook 2 { 3 public enum HookType 4 { 5 MsgFilter = -1, 6 7 JournalRecord = 0, 8 9 JournalPlayback = 1, 10 11 Keyboard = 2, 12 13 GetMessage = 3, 14 15 CallWndProc = 4, 16 17 CBT = 5, 18 19 SysMsgFilter = 6, 20 21 Mouse = 7, 22 23 Hardware = 8, 24 25 Debug = 9, 26 27 Shell = 10, 28 29 ForegroundIdle = 11, 30 31 CallWndProcRet = 12, 32 33 KeyboardLL = 13, 34 35 MouseLL = 14 36 } 37 }
钩子核心调用方法
1 amespace CSharpHook 2 { 3 public delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam); 4 public class CSHook 5 { 6 [DllImport("kernel32.dll")] 7 public static extern int GetCurrentThreadId(); //取得当前线程编号的API 8 9 [DllImport("User32.dll")] 10 public extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API 11 12 [DllImport("User32.dll")] 13 public extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(System.Runtime.InteropServices.UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API 14 15 [DllImport("User32.dll")] 16 public extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API 17 } 18 }
钩子业务调用类
1 namespace CSharpHook 2 { 3 public abstract class MyHookProcBase 4 { 5 protected IntPtr _nextHookPtr; //记录Hook编号 6 protected CSharpHook.HookType hookType; 7 protected int threadID; 8 public void SetHook() 9 { 10 if (_nextHookPtr != IntPtr.Zero) 11 {//已经勾过了 12 return; 13 } 14 //CSharpHook.HookProc myhookProc = new CSharpHook.HookProc(this.Proc); //声明一个自己的Hook实现函数的委托对象 15 16 _nextHookPtr = CSharpHook.CSHook.SetWindowsHookEx((int)hookType, new CSharpHook.HookProc(this.Proc), IntPtr.Zero, this.threadID); //加到Hook链中 17 18 } 19 20 public void UnHook() 21 { 22 23 if (_nextHookPtr != IntPtr.Zero) 24 { 25 26 CSharpHook.CSHook.UnhookWindowsHookEx(_nextHookPtr);//从Hook链中取消 27 _nextHookPtr = IntPtr.Zero; 28 } 29 30 } 31 protected abstract IntPtr Proc(int code, IntPtr wparam, IntPtr lparam); 32 } 33 34 }
上面是一个类库
下面将创建一个Winform程序实现对本程序的键盘侦听
下面是代码
----------------
本程序具体的钩子业务逻辑
1 namespace HookTool 2 { 3 public class MyHook : CSharpHook.MyHookProcBase 4 { 5 public int ThreadID 6 { 7 get { 8 return base.threadID; 9 } 10 set { 11 base.threadID = value; 12 } 13 } 14 public MyHook(CSharpHook.HookType ht) { 15 base.hookType = ht; 16 } 17 public System.Windows.Forms.ListBox lbMsg; 18 protected override IntPtr Proc(int code, IntPtr wparam, IntPtr lparam) 19 { 20 if (code < 0) 21 { 22 return CSharpHook.CSHook.CallNextHookEx(this._nextHookPtr, code, wparam, lparam); //返回,让后面的程序处理该消息 23 } 24 25 if ((lparam.ToInt32() & 0x40000000)>0) 26 { 27 //this.textBox1.Text = "a"; 28 this.lbMsg.Items.Add((char)wparam.ToInt32()); 29 return (IntPtr)1; //直接返回了,该消息就处理结束了 30 } 31 else 32 { 33 return IntPtr.Zero; //返回,让后面的程序处理该消息 34 } 35 } 36 } 37 }
Winform主程序
1 namespace HookTool 2 { 3 public partial class Hook : Form 4 { 5 MyHook mh; 6 public Hook() 7 { 8 InitializeComponent(); 9 } 10 11 private void Hook_Load(object sender, EventArgs e) 12 { 13 mh=new MyHook(CSharpHook.HookType.Keyboard); 14 this.lvProcess.Columns.AddRange(new ColumnHeader[]{ 15 new ColumnHeader(){ Text="进程ID"}, 16 new ColumnHeader(){ Text="进程名称"}, 17 new ColumnHeader(){ Text="线程数"} 18 }); 19 this.lvProcess.View = View.Details; 20 GetProcess(); 21 } 22 23 private void Hook_FormClosing(object sender, FormClosingEventArgs e) 24 { 25 mh.UnHook(); 26 } 27 28 private void bMonitor_Click(object sender, EventArgs e) 29 { 30 mh.ThreadID = CSharpHook.CSHook.GetCurrentThreadId(); 31 mh.lbMsg = this.lbMsg; 32 33 mh.SetHook(); 34 } 35 void GetProcess() { 36 this.lvProcess.Items.Clear(); 37 System.Diagnostics.Process[] ps=System.Diagnostics.Process.GetProcesses(); 38 foreach (System.Diagnostics.Process p in ps) { 39 this.lvProcess.Items.Add(new ListViewItem(new string[]{ 40 p.Id.ToString(), 41 p.ProcessName, 42 p.Threads.Count.ToString() 43 })); 44 } 45 } 46 47 private void bRefresh_Click(object sender, EventArgs e) 48 { 49 GetProcess(); 50 } 51 52 private void bClose_Click(object sender, EventArgs e) 53 { 54 this.Close(); 55 System.Environment.Exit(0); 56 } 57 } 58 }
篇幅所限 不做详细说明