c# 禁用鼠标与键盘
2018-03-12 11:14
393 查看
禁用鼠标与键盘有两种方法:
直接调用禁用API(缺点:按Ctrl+alt+delete,禁用会失效)
① 帮助类
使用钩子(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早已退出历史舞台,这个前缀也就约定俗成的沿用下来了。**
具体代码
② 窗体测试
源码下载地址:https://download.csdn.net/download/qq_37477609/10281656
直接调用禁用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); }
使用钩子(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() 9e47 == "A") { hkb.Hook_Clear(); } } } }
源码下载地址:https://download.csdn.net/download/qq_37477609/10281656
相关文章推荐
- C#模拟键盘鼠标事件
- C#模拟键盘鼠标之一
- 禁用U盘,但不禁用USB鼠标键盘
- C#(Winform)禁用TextBox控件的鼠标事件
- C#模拟鼠标键盘控制其他窗口(一)
- 使用C#模拟键盘输入、鼠标移动和点击、设置光标位置及控制应用程序的显示
- c# 实现锁屏及禁止键盘和鼠标
- 禁用USB口导致键盘鼠标不能使用
- C# WinForm 鼠标事件 键盘事件
- c# 如何获取键盘和鼠标处于空闲状态的时间
- C#模拟鼠标键盘控制其他窗口
- 在Linux下禁用键盘、鼠标、触摸板(笔记本)等输入设备
- C#钩子类 几乎捕获键盘鼠标所有事件
- c#使用钩子拦截鼠标键盘事件
- 关于禁用USB存储设备,而不禁使用USB键盘,鼠标
- C#键盘鼠标钩子实例
- C#: 鼠标和键盘的输入事件
- C#实现鼠标、键盘钩子
- [译]如何在Linux下禁用键盘、触摸板、鼠标等输入设备
- C#模拟键盘鼠标事件