阅读量:0
在C#项目中,可以使用全局钩子(Global Hooks)来监视和捕获系统范围内的键盘和鼠标事件
- 首先,需要添加对
System.Windows.Forms
和System.Runtime.InteropServices
命名空间的引用。
using System; using System.Windows.Forms; using System.Runtime.InteropServices;
- 定义一个类来处理全局钩子。在这个类中,我们将使用P/Invoke来调用Windows API函数。
public class GlobalHook { // 定义钩子类型 public enum HookType { WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 } // 定义鼠标钩子结构体 [StructLayout(LayoutKind.Sequential)] public struct MouseHookStruct { public Point pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; } // 定义键盘钩子结构体 [StructLayout(LayoutKind.Sequential)] public struct KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } // 导入SetWindowsHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId); // 导入UnhookWindowsHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); // 导入CallNextHookEx函数 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); // 导入GetModuleHandle函数 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); // 定义钩子回调委托 public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); // 定义钩子事件 public event EventHandler<MouseEventArgs> MouseEvent; public event EventHandler<KeyEventArgs> KeyEvent; private IntPtr _hookID = IntPtr.Zero; private readonly HookProc _hookProc; public GlobalHook() { _hookProc = HookCallback; } // 安装钩子 public void InstallHook(HookType hookType) { if (_hookID != IntPtr.Zero) return; IntPtr moduleHandle = GetModuleHandle(null); _hookID = SetWindowsHookEx((int)hookType, _hookProc, moduleHandle, 0); } // 卸载钩子 public void UninstallHook() { if (_hookID == IntPtr.Zero) return; UnhookWindowsHookEx(_hookID); _hookID = IntPtr.Zero; } // 钩子回调函数 private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) { if (_hookID != IntPtr.Zero) { switch ((HookType)_hookID.ToInt32()) { case HookType.WH_MOUSE_LL: MouseHookStruct mouseData = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); MouseEvent?.Invoke(this, new MouseEventArgs(mouseData.pt)); break; case HookType.WH_KEYBOARD_LL: KeyboardHookStruct keyData = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); KeyEvent?.Invoke(this, new KeyEventArgs(keyData.vkCode)); break; } } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } }
- 在你的应用程序中使用
GlobalHook
类来监听键盘和鼠标事件。
public partial class MainForm : Form { private readonly GlobalHook _globalHook; public MainForm() { InitializeComponent(); _globalHook = new GlobalHook(); _globalHook.MouseEvent += OnMouseEvent; _globalHook.KeyEvent += OnKeyEvent; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); // 安装钩子 _globalHook.InstallHook(GlobalHook.HookType.WH_MOUSE_LL); _globalHook.InstallHook(GlobalHook.HookType.WH_KEYBOARD_LL); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); // 卸载钩子 _globalHook.UninstallHook(); } private void OnMouseEvent(object sender, MouseEventArgs e) { Console.WriteLine($"Mouse event: {e.Location}"); } private void OnKeyEvent(object sender, KeyEventArgs e) { Console.WriteLine($"Key event: {e.KeyValue}"); } }
这样,你就可以在C#项目中使用全局钩子来监视和捕获系统范围内的键盘和鼠标事件了。请注意,全局钩子可能会影响系统性能,因此在不需要时,务必及时卸载钩子。