在C#中实现鼠标和键盘事件的全局捕获,通常要借助Windows提供的钩子机制。全局钩子可以监控系统范围内的输入消息,不管当前焦点在哪个窗口。其核心是调用user32.dll中的SetWindowsHookEx函数,将自定义回调挂入系统消息链。

什么是全局钩子
全局钩子(Global Hook)是Windows允许应用程序在系统消息到达目标窗口前先进行拦截处理的一种机制。根据监听类型不同,可分为键盘钩子(WH_KEYBOARD_LL)和鼠标钩子(WH_MOUSE_LL)等。低层钩子不需要注入到其他进程,因此在C#中更容易实现。
C#调用Win32 API的基础
我们需要通过DllImport引入user32和kernel32的方法。下面代码展示关键API声明:
using System;
using System.Runtime.InteropServices;
public class Win32
{
// 安装钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelProc lpfn, IntPtr hMod, uint dwThreadId);
// 卸载钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
// 传递钩子消息给下一个处理者
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
// 获取模块句柄
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
// 低级键盘和鼠标钩子类型
public const int WH_KEYBOARD_LL = 13;
public const int WH_MOUSE_LL = 14;
public delegate IntPtr LowLevelProc(int nCode, IntPtr wParam, IntPtr lParam);
}
键盘事件捕获实现
使用WH_KEYBOARD_LL可以捕获按键。回调中通过lParam转换为结构体读取虚拟键码。下面示例演示如何安装并处理键盘钩子:
using System;
using System.Runtime.InteropServices;
public class KeyboardHook
{
private IntPtr hookId = IntPtr.Zero;
private Win32.LowLevelProc proc;
public void Start()
{
proc = HookCallback;
using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule)
{
// 第四个参数为0表示全局钩子
hookId = Win32.SetWindowsHookEx(Win32.WH_KEYBOARD_LL, proc, Win32.GetModuleHandle(curModule.ModuleName), 0);
}
}
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine("按键虚拟码: " + vkCode);
}
return Win32.CallNextHookEx(hookId, nCode, wParam, lParam);
}
public void Stop()
{
Win32.UnhookWindowsHookEx(hookId);
}
}
鼠标事件捕获原理
鼠标全局钩子与键盘类似,只是idHook使用WH_MOUSE_LL。在回调里读取MSLLHOOKSTRUCT可获得坐标和按键状态。由于低层钩子运行在调用线程,必须保证安装钩子的线程有消息循环,否则钩子会失效。
底层实现原理
系统在处理输入时,会将消息发送给注册的钩子链。低层钩子由内核在接收到设备输入后调用,通过回调进入用户态的C#方法。因为托管代码需要保持稳定,回调不应做耗时操作,且必须调用CallNextHookEx保证消息传递。
注意事项
- 全局钩子可能影响系统性能,应及时卸载。
- 低层钩子虽不需注入,但仍需程序持续运行消息循环。
- 在UI线程或单独线程中运行,避免界面卡死。
小结
通过SetWindowsHookEx配合低级钩子类型,C#能够以较小代价实现全局鼠标和键盘事件捕获。理解其底层消息传递与回调机制,有助于编写稳定且安全的输入监听程序。
C#全局钩子鼠标键盘事件HookSetWindowsHookEx修改时间:2026-07-29 19:06:28