【Net】一个简单的键盘钩子

最近在写一个采集程序

需要用到钩子

为了学习钩子 特写了个小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 }

篇幅所限 不做详细说明

posted @ 2013-05-09 15:39  哈哈好玩  阅读(380)  评论(0)    收藏  举报