C# 封装一个钩子类

利用C#设置钩子函数,并封装成类。如果想要实现全局钩子的话,必须将实现的代码封装到类库里。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Forms; namespace PublicHook
{
/// <summary>
///存放回调函数的委托
/// </summary>
public delegate int HOOKPROC(int nCode, IntPtr wParam, IntPtr lParam);
public enum HookType
{
WH_KEYBOARD = , //私有键盘钩子
WH_EKYBOARD_LL = , //全局键盘钩子
WH_MOUSE = , //私有鼠标钩子
WH_MOUSE_LL = //全局鼠标钩子
} public abstract class hook
{
//设置钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(HookType idHook, HOOKPROC lpfn, IntPtr hInstance, int threadId);
//取下钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//获取当前线程一个唯一的线程标识符
[DllImport("kernel32")]
public static extern int GetCurrentThreadId();
//传递消息给下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
//获取一个应用程序或动态链接库的模块句柄
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name); /// <summary>
/// 钩子处理委托
/// </summary>
public HOOKPROC proc;
/// <summary>
/// 钩子类型
/// </summary>
public HookType type;
/// <summary>
/// 钩子的句柄
/// </summary>
public int hHook = ; public hook(HOOKPROC proc, HookType type)
{
this.proc = proc;
this.type = type;
}
//设置回调函数
public void SetProc(HOOKPROC proc)
{
this.proc = proc;
} public abstract int SetWindowsHookEx();
public virtual void UnhookWindowsHookEx()
{
bool retKeyboard = true;
//当前钩子句柄不为空,卸载钩子
if (hHook != )
{
retKeyboard = UnhookWindowsHookEx(hHook);
hHook = ;
}
if (!retKeyboard)
throw new Exception("UnhookWindowsHookEx failed.");
}
} public class PublicKBHook : hook
{
public PublicKBHook(HOOKPROC proc)
: base(proc, HookType.WH_EKYBOARD_LL)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), );
return hHook;
} //Hook结构
[StructLayout(LayoutKind.Sequential)]
public class HookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
/// <summary>
///回调函数,屏蔽除了回车和tab之外的所有键盘消息
/// </summary>
public int MyKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if ( nCode >= )
{
HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure((IntPtr)lParam, typeof(HookStruct));
//如果按下了回车,则将消息传给下一个钩子
if ((Keys)hookStruct.vkCode == Keys.Enter ||
(Keys)hookStruct.vkCode == Keys.Tab)
return CallNextHookEx(hHook, nCode, wParam, lParam);
//后门
if ((Keys)hookStruct.vkCode == Keys.F1)
UnhookWindowsHookEx( hHook );
} return ;
}
} public class PrivateKBHook : hook
{
public PrivateKBHook(HOOKPROC proc)
: base(proc, HookType.WH_KEYBOARD)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId());
return hHook;
}
} public class PublicMouseHook : hook
{
public PublicMouseHook(HOOKPROC proc)
: base(proc, HookType.WH_MOUSE_LL)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), );
return hHook;
} /// <summary>
/// 屏蔽除了鼠标移动之外的鼠标消息
/// </summary>
public int MyMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
//当wParam = 0x0200 时,进行鼠标移动操作
//直接将消息传递给下一个钩子
if (wParam == (IntPtr)0x0200)
return CallNextHookEx(hHook, nCode, wParam, lParam); return ;
}
} public class PrivateMouseHook : hook
{
public PrivateMouseHook(HOOKPROC proc)
: base(proc, HookType.WH_MOUSE)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId()); return hHook;
}
}
}

调用代码:

            //钩子句柄
int hKBHook = , hMouseHook = ;
//设置全局键盘钩子
PublicKBHook myKBHook = new PublicKBHook(null);
myKBHook.SetProc(myKBHook.MyKeyboardProc);
hKBHook = myKBHook.SetWindowsHookEx();

卸载钩子:

//撤销钩子
myKBHook.UnhookWindowsHookEx();
上一篇:读书笔记 effective c++ Item 26 尽量推迟变量的定义


下一篇:linux中历史命令的一点发现