C#鍵盤按鍵監視

主要代碼: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;函數

原文連接爲:http://www.mzwu.com/article.asp?id=2208測試

相關文章
相關標籤/搜索