winform使用钩子限制windows热键
阅读原文时间:2023年07月13日阅读:1

新增类KeybordHookProc

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace HookDemo
{
///

/// 这个类可以让你得到一个在运行中程序的所有键盘事件 /// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息 ///
public class KeyBordHook
{

    private const byte LLKHF\_ALTDOWN = 0x20;  
    private const byte VK\_CAPITAL = 0x14;  
    private const byte VK\_ESCAPE = 0x1B;  
    private const byte VK\_F4 = 0x73;  
    private const byte VK\_LCONTROL = 0xA2;  
    private const byte VK\_NUMLOCK = 0x90;  
    private const byte VK\_RCONTROL = 0xA3;  
    private const byte VK\_SHIFT = 0x10;  
    private const byte VK\_TAB = 0x09;  
    public const int WH\_KEYBOARD = ;  
    private const int WH\_MOUSE = ;  
    private const int WH\_MOUSE\_LL = ;  
    private const int WM\_KEYDOWN = 0x100;  
    private const int WM\_KEYUP = 0x101;  
    private const int WM\_LBUTTONDBLCLK = 0x203;  
    private const int WM\_LBUTTONDOWN = 0x201;  
    private const int WM\_LBUTTONUP = 0x202;  
    private const int WM\_MBUTTONDBLCLK = 0x209;  
    private const int WM\_MBUTTONDOWN = 0x207;  
    private const int WM\_MBUTTONUP = 0x208;  
    private const int WM\_MOUSEMOVE = 0x200;  
    private const int WM\_MOUSEWHEEL = 0x020A;  
    private const int WM\_RBUTTONDBLCLK = 0x206;  
    private const int WM\_RBUTTONDOWN = 0x204;  
    private const int WM\_RBUTTONUP = 0x205;  
    private const int WM\_SYSKEYDOWN = 0x104;  
    private const int WM\_SYSKEYUP = 0x105;

    //全局的事件  
    public event KeyEventHandler OnKeyDownEvent;  
    public event KeyEventHandler OnKeyUpEvent;  
    public event KeyPressEventHandler OnKeyPressEvent;

    static int hKeyboardHook = ; //键盘钩子句柄

    //鼠标常量  
    public const int WH\_KEYBOARD\_LL = ; //keyboard hook constant

    HookProc KeyboardHookProcedure; //声明键盘钩子事件类型.

    //声明键盘钩子的封送结构类型  
    \[StructLayout(LayoutKind.Sequential)\]  
    public class KeyboardHookStruct  
    {  
        public int vkCode; //表示一个在1到254间的虚似键盘码  
        public int scanCode; //表示硬件扫描码  
        public int flags;  
        public int time;  
        public int dwExtraInfo;  
    }

    //装置钩子的函数  
    \[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)\]  
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

    //卸下钩子的函数  
    \[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)\]  
    public static extern bool UnhookWindowsHookEx(int idHook);

    //下一个钩挂的函数  
    \[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)\]  
    public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

    //取得当前线程编号  
    \[DllImport("kernel32.dll")\]  
    private static extern int GetCurrentThreadId();

    \[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)\]  
    private static extern short GetKeyState(int vKey);

    public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

    /// <summary>  
    /// 墨认的构造函数构造当前类的实例并自动的运行起来.  
    /// </summary>  
    public KeyBordHook()  
    {  
        Start();  
    }

    //析构函数.  
    ~KeyBordHook()  
    {  
        Stop();  
    }

    /// <summary>  
    /// 启动Hook,并用流屏蔽任务管理器  
    /// </summary>  
    public void Start()  
    {  
        if (hKeyboardHook == )  
        {  
            //   创建HookProc实例  
            KeyboardHookProcedure = new HookProc(KeyboardHookProc);

            hKeyboardHook = SetWindowsHookEx(WH\_KEYBOARD,  
                KeyboardHookProcedure,  
                Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()\[\]),  
                );

            //   如果设置钩子失败  
            if (hKeyboardHook == )  
            {  
                Stop();  
                AppLog.Error("SetWindowsHookEx failed.");  
            }

            ////用二进制流的方法打开任务管理器。而且不关闭流.这样任务管理器就打开不了  
            //MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%\\\\system32\\\\taskmgr.exe"),  
            //    FileMode.Open);  
            //byte\[\] MyByte = new byte\[(int)MyFs.Length\];  
            //MyFs.Write(MyByte, 0, (int)MyFs.Length);  
        }  
    }

    /// <summary>  
    /// 卸载Hook  
    /// </summary>  
    public void Stop()  
    {  
        bool retKeyboard = true;

        if (hKeyboardHook != )  
        {  
            retKeyboard = UnhookWindowsHookEx(hKeyboardHook);

            hKeyboardHook = ;  
        }

        //if (null != MyFs)  
        //{  
        //    MyFs.Close();  
        //}

        if (!(retKeyboard))  
        {  
            AppLog.Error("UnhookWindowsHookEx failed.");  
        }  
    }

    #region Nested type: KeyMSG

    public struct KeyMSG  
    {  
        public int dwExtraInfo;  
        public int flags;  
        public int scanCode;

        public int time;  
        public int vkCode;  
    }

    #endregion

    /// <summary>  
    /// 键盘钩子  
    /// </summary>  
    /// <param name="nCode"></param>  
    /// <param name="wParam"></param>  
    /// <param name="lParam"></param>  
    /// <returns></returns>  
    private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)  
    {  
        KeyboardHookStruct m = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

        AppLog.Debug($"nCode is :{nCode} -- vkCode is :{m.vkCode}");  
        if (m.vkCode == (int)Keys.LWin ||  
            m.vkCode == (int)Keys.RWin ||  
            m.vkCode == (int)Keys.LWin && m.vkCode == (int)Keys.D ||  
            m.vkCode == (int)Keys.RWin && m.vkCode == (int)Keys.D ||  
            m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control ||  
            m.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt ||  
            m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt ||  
            m.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt ||  
            m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift ||  
            (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete  
        )  
        {  
            AppLog.Info("hooc is OK");  
            return ;  
        }

        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);  
    }

}  

}

添加键盘按键触发事件

///

/// 键盘按下触发事件 ///
void kh_OnKeyDownEvent(object sender, KeyEventArgs e)
{

}

键盘钩子的使用

///

/// 键盘钩子 ///
KeyBordHook _keyBordHook;

//键盘钩子实例化
_keyBordHook = new KeyBordHook();
_keyBordHook.OnKeyDownEvent += kh_OnKeyDownEvent;