在C#项目中如何管理全局钩子

avatar
作者
猴君
阅读量:0

在C#项目中,可以使用全局钩子(Global Hooks)来监视和捕获系统范围内的键盘和鼠标事件

  1. 首先,需要添加对System.Windows.FormsSystem.Runtime.InteropServices命名空间的引用。
using System; using System.Windows.Forms; using System.Runtime.InteropServices; 
  1. 定义一个类来处理全局钩子。在这个类中,我们将使用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);     } } 
  1. 在你的应用程序中使用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#项目中使用全局钩子来监视和捕获系统范围内的键盘和鼠标事件了。请注意,全局钩子可能会影响系统性能,因此在不需要时,务必及时卸载钩子。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!