c# 禁用鼠标与键盘

禁用鼠标与键盘有两种方法:

  1. 直接调用禁用API(缺点:按Ctrl+alt+delete,禁用会失效)

① 帮助类

    public class BlockHelper
    {
        private static Logger<BlockHelper> log = new Logger<BlockHelper>();
        private const int SE_PRIVILEGE_ENABLED = 0x00000002;
        private const int TOKEN_QUERY = 0x00000008;
        private const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        private struct TokPriv1Luid
        {
            public int Count;
            public long Luid;
            public int Attr;
        }

        public static bool off()
        {
            if (IsAdministrator())
            {
                BlockInput(true);//锁定鼠标及键盘
                return true;
            }
            else
                return false;
        }
        public static bool on()
        {
            if (IsAdministrator())
            {
                BlockInput(false);//解除键盘鼠标锁定
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 是否是管理员权限
        /// </summary>
        /// <returns></returns>
        public static bool IsAdministrator()
        {
            WindowsIdentity current = WindowsIdentity.GetCurrent();
            WindowsPrincipal windowsPrincipal = new      WindowsPrincipal(current);
            return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        [DllImport("user32.dll")]
        static extern void BlockInput(bool Block);
    }
  1. 使用钩子(HOOK)截取信息进行处理

钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

函数:HHOOK WINAPI SetWindowsHookEx(
__in int idHook, \钩子类型
__in HOOKPROC lpfn, \回调函数地址
__in HINSTANCE hMod, \实例句柄
__in DWORD dwThreadId); \线程ID

其中ipfn是回调函数
LRESULT CALLBACK HookProc
(
int nCode,
WPARAM wParam,
LPARAM lParam
);
HookProc是回调函数名。

**注:WPARAM,消息响应机制
wParam和lParam 这两个是Win16系统遗留下来的产物,在Win16API中WndProc有两个参数:
一个是WORD类型的16位整型变量;另一个是LONG类型的32位整型变量。因此根据匈牙利命名法,16位的变量就被命名为wParam, 32位的变量就被命名为lParam。
到了Win32API中,原来的16位变量也被扩展为32位,因此此时wParam和lParam的大小完全相同。
在Win32API的早期,为了保证和Win16API的代码可移植性MS定义了WPARAM和LPARAM两个宏。
当时保留了w前缀的原因一方面是由于WPARAM宏也以W开头,还有也因为要提醒程序员注意到可移植性,当然到了现在Win16早已退出历史舞台,这个前缀也就约定俗成的沿用下来了。**

具体代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HookTest
{
    public class HookKeyBoard
    {
        private enum HookType
        {
            WH_CALLWNDPROC = 4, //安装在系统将消息发送到目标窗口过程之前监视邮件的挂钩过程。
            WH_CALLWNDPROCRET = 12, //安装在目标窗口过程处理完邮件后监视消息的挂钩过程。
            WH_CBT = 5, //安装接收对 CBT 应用程序有用的通知的挂钩过程。
            WH_DEBUG = 9, //安装用于调试其他挂钩过程的挂钩过程。
            WH_FOREGROUNDIDLE = 11, //安装将在应用程序的前景线程即将变为空闲时调用的挂钩过程。此挂钩对于在空闲时间执行低优先级任务非常有用。
            WH_GETMESSAGE = 3, //安装用于监视张贴到消息队列的邮件的挂钩过程。
            WH_HARDWARE = 8, //安装一个挂接过程, 用于张贴以前由 WH_JOURNALRECORD 挂钩过程记录的消息。
            WH_JOURNALPLAYBACK = 1, //安装一个挂接过程, 用于张贴以前由 WH_JOURNALRECORD 挂钩过程记录的消息。
            WH_JOURNALRECORD = 0,//安装用于记录张贴到系统消息队列中的输入消息的挂钩过程。
            WH_KEYBOARD = 2,//安装监视击键消息的挂钩过程。
            WH_MOUSE = 7,//安装监视鼠标消息的挂钩过程。
            WH_MSGFILTER = (-1), //安装一个钩子过程, 用于监视对话框、消息框、菜单或滚动条中由于输入事件而生成的消息。
            WH_SHELL = 10,//安装接收对 shell 应用程序有用的通知的挂钩过程。
            WH_SYSMSGFILTER = 6,//安装一个钩子过程, 用于监视对话框、消息框、菜单或滚动条中由于输入事件而生成的消息。挂钩过程监视与调用线程在同一桌面上的所有应用程序的这些消息。
            WH_KEYBOARD_LL = 13,//安装用于监视低级键盘输入事件的挂钩过程。
            WH_MOUSE_LL = 14,//安装用于监视低级别鼠标输入事件的挂钩过程。
        }

        private const int WM_KEYUP = 0X101;
        private const int WM_SYSKEYUP = 0X105;

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

        private int KeyHook;

        private int MouseHook;

        public event KeyEventHandler keyeventhandler;

        [StructLayout(LayoutKind.Sequential)]
        private class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //设置钩子 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]  
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);// 钩子类型 回调函数地址 实例句柄 线程ID

        //卸载钩子 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]    
        private static extern bool UnhookWindowsHookEx(int idHook); //要移除的钩子的句柄。此参数是由以前对 SetWindowsHookEx 的调用获取的挂钩句柄。

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name); //获取进程句柄

        [DllImport("user32", EntryPoint = "GetMessage")]
        public static extern int GetMessage(  //调用线程的消息队列里取得一个消息并将其放于指定的结构.此函数可取得与指定窗口联系的消息和由PostThreadMessage寄送的线程消息
                        out tagMSG lpMsg,//指向MSG结构的指针,该结构从线程的消息队列里接收消息信息。
                        IntPtr hwnd,//取得其消息的窗口的句柄。当其值取NULL时,GetMessage为任何属于调用线程的窗口检索消息,线程消息通过PostThreadMessage寄送给调用线程。
                        int wMsgFilterMin,//指定被检索的最小消息值的整数。
                        int wMsgFilterMax//指定被检索的最大消息值的整数。
        );
        [DllImport("user32", EntryPoint = "DispatchMessage")]
        public static extern int DispatchMessage(ref tagMSG lpMsg); //函数将键盘消息转化

        [DllImport("user32", EntryPoint = "TranslateMessage")]
        public static extern int TranslateMessage(ref tagMSG lpMsg); //函数将消息传给窗体函数去处理
        public struct tagMSG
        {
            public int hwnd;
            public uint message;
            public int wParam;
            public long lParam;
            public uint time;
            public int pt;
        }


        public void InstallHook(Form form)
        {
            if (KeyHook.Equals(0))
            {
                HookProc hp = new HookProc(KeyMouseHookProc);
                KeyHook = SetWindowsHookEx((int)HookType.WH_KEYBOARD_LL,
                          hp,
                        GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
                MouseHook = SetWindowsHookEx((int)HookType.WH_MOUSE_LL, hp,
                    GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
            }
            if (KeyHook.Equals(0) && MouseHook.Equals(0)) {
                Hook_Clear();
                throw new Exception("安装钩子失败");
            }
        }

        /// <summary>
        /// 自己想要的信息处理 
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int KeyMouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            if (keyeventhandler != null && nCode >= 0) {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) {
                    Keys keyData = (Keys)kbh.vkCode;
                    KeyEventArgs e = new KeyEventArgs(keyData);
                    keyeventhandler(this, e);
                }
            }
            return 1;
        }

        //取消钩子事件 
        public void Hook_Clear()
        {
            bool retKeyboard = true;
            if (!KeyHook.Equals(0) && !MouseHook.Equals(0))
            {
                retKeyboard = UnhookWindowsHookEx(KeyHook);
                if (retKeyboard) retKeyboard = UnhookWindowsHookEx(MouseHook);
            }
            //如果去掉钩子失败. 
            if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
        }
    }
}

② 窗体测试

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HookTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private HookKeyBoard hkb = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            DisabledMouseKey();
        }

        private void DisabledMouseKey()
        {
            hkb = new HookKeyBoard();
            hkb.keyeventhandler += new KeyEventHandler(keyhandler);
            hkb.InstallHook(this);
            HookKeyBoard.tagMSG Msgs;
            while (HookKeyBoard.GetMessage(out Msgs, IntPtr.Zero, 0, 0) > 0)
            {
                HookKeyBoard.TranslateMessage(ref Msgs);
                HookKeyBoard.DispatchMessage(ref Msgs);
            }
        }

        private void EnableMouseKey()
        {
            hkb.Hook_Clear();
        }

        /// <summary>
        /// 设立一个口子,以防禁用完还得重启
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void keyhandler(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyData.ToString() == "a" || e.KeyData.ToString() == "A")
            {
                hkb.Hook_Clear();
            }
        }
    }
}
  1. 源码下载地址:https://download.csdn.net/download/qq_37477609/10281656
    原文作者:Super毛毛虫
    原文地址: https://blog.csdn.net/qq_37477609/article/details/79524410
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞