在C#項目中,可以使用全局鉤子(Global Hooks)來監視和捕獲系統范圍內的鍵盤和鼠標事件
System.Windows.Forms
和System.Runtime.InteropServices
命名空間的引用。using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
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#項目中使用全局鉤子來監視和捕獲系統范圍內的鍵盤和鼠標事件了。請注意,全局鉤子可能會影響系統性能,因此在不需要時,務必及時卸載鉤子。