主要代碼:InterceptKeys.cs:c#
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; namespace WindowsApplication1 { /// <summary> /// 獲取鍵盤按鍵 /// </summary> /// <example> /// InterceptKeys.RunHook(); /// </example> public class InterceptKeys { private const int WH_KEYBOARD_LL = 13; //全局鍵盤鉤子 private const int WM_KEYDOWN = 0x0100; //鍵盤按下 //private const int WM_KEYUP = 0x0101; //鍵盤擡起 private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; #region 調用API private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); /// <summary> /// 安裝鉤子 /// </summary> /// <param name="idHook">鉤子類型</param> /// <param name="lpfn">函數指針</param> /// <param name="hMod">包含鉤子函數的模塊(EXE、DLL)句柄; 通常是 HInstance; 若是是當前線程這裏能夠是 0</param> /// <param name="dwThreadId">關聯的線程; 可用 GetCurrentThreadId 獲取當前線程; 0 表示是系統級鉤子</param> /// <returns>返回鉤子的句柄; 0 表示失敗</returns> [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); //鉤子類型 idHook 選項: //WH_MSGFILTER = -1; {線程級; 截獲用戶與控件交互的消息} //WH_JOURNALRECORD = 0; {系統級; 記錄全部消息隊列從消息隊列送出的輸入消息, 在消息從隊列中清除時發生; 可用於宏記錄} //WH_JOURNALPLAYBACK = 1; {系統級; 回放由 WH_JOURNALRECORD 記錄的消息, 也就是將這些消息從新送入消息隊列} //WH_KEYBOARD = 2; {系統級或線程級; 截獲鍵盤消息} //WH_GETMESSAGE = 3; {系統級或線程級; 截獲從消息隊列送出的消息} //WH_CALLWNDPROC = 4; {系統級或線程級; 截獲發送到目標窗口的消息, 在 SendMessage 調用時發生} //WH_CBT = 5; {系統級或線程級; 截獲系統基本消息, 譬如: 窗口的建立、激活、關閉、最大最小化、移動等等} //WH_SYSMSGFILTER = 6; {系統級; 截獲系統範圍內用戶與控件交互的消息} //WH_MOUSE = 7; {系統級或線程級; 截獲鼠標消息} //WH_HARDWARE = 8; {系統級或線程級; 截獲非標準硬件(非鼠標、鍵盤)的消息} //WH_DEBUG = 9; {系統級或線程級; 在其餘鉤子調用前調用, 用於調試鉤子} //WH_SHELL = 10; {系統級或線程級; 截獲發向外殼應用程序的消息} //WH_FOREGROUNDIDLE = 11; {系統級或線程級; 在程序前臺線程空閒時調用} //WH_CALLWNDPROCRET = 12; {系統級或線程級; 截獲目標窗口處理完畢的消息, 在 SendMessage 調用後發生} /// <summary> /// 卸載鉤子 /// </summary> /// <param name="hhk">鉤子的句柄</param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); #endregion /// <summary> /// 安裝鉤子 /// </summary> public static void RunHook() { _hookID = SetHook(_proc); } /// <summary> /// 卸載鉤子 /// </summary> public static void UnHook() { UnhookWindowsHookEx(_hookID); } /// <summary> /// 安裝鉤子 /// </summary> /// <param name="proc"></param> /// <returns></returns> private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } /// <summary> /// 處理函數 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns> /// 若是返回1,則結束消息,這個消息到此爲止,再也不傳遞; /// 若是返回0或調用CallNextHookEx函數則消息出了這個鉤子繼續往下傳遞,也就是傳給消息真正的接受者; /// </returns> private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { //鍵盤按下時 if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { int vkCode = Marshal.ReadInt32(lParam); Keys key = (Keys)vkCode; //記錄到日誌 System.IO.File.AppendAllText(@"C:\hot.txt", DateTime.Now.ToString("HH:mm:ss") + ": " + key.ToString() + "\r\n"); } return CallNextHookEx(_hookID, nCode, wParam, lParam); } } }
開始調用:ide
InterceptKeys.RunHook();
上面的代碼本身測試了一下,須要放在winform下使用,由於其中用到的Keys引用的命名空間是System.Windows.Forms;函數