禁用系统热键(包括禁止使用任务管理器)

一般来说会用到hook(钩子),即获取系统的按键或者鼠标动作,然后在系统响应之前执行自定义动作,或者直接截断这个消息,
这就是屏蔽系统热键的原理了。
首先要调用操作系统的dll文件,先引入命名空间
using System.Runtime.InteropServices; 

调用操作系统动态链接库的方法

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookExW(int idHook, HookHandlerDelegate lpfn, IntPtr hmod, uint dwThreadID);

第一个参数代表钩子ID(13代表键盘钩子,14代表鼠标钩子),第二个参数是一个函数指针,指向钩子需要执行的函数,第三个参数是指向进程块的指针,第四个参数默认为0就行了。

再引用一个获取进程块指针的方法

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 

public static extern IntPtr GetModuleHandle(String modulename);
接下来就是构造一个钩子了(以键盘钩子为例)
定义常量:
public const int WM_KEYDOWN = 0x0100;
public const int WH_KEYBOARD_LL = 13;
public const int WM_SYSKEYDOWN = 0x0104;

定义储存按键信息的结构体:

public struct KBDLLHOOKSTRUCT
{
       public int vkCode;
       public int scanCode;
       public int flags;
       public int time;
       public int dwExtraInfo;
}

定义一个函数指针:

public delegate int HookHandlerDelegate(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam);

声明一个指向执行函数的函数指针:

private HookHandlerDelegate proc;

构造钩子:

        public void disableKeys()
        {
            proc = new HookHandlerDelegate(HookCallback);
            using (Process curPro = Process.GetCurrentProcess())
            using (ProcessModule curMod = curPro.MainModule)
            {
                SetWindowsHookExW(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.ModuleName), 0);
            }
        }    

HookCallback即为钩子执行的函数

private int HookCallback(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam)
{
    if (nCode >= 0 && (wparam == (IntPtr)WM_KEYDOWN || wparam == (IntPtr)WM_SYSKEYDOWN))
    {
        if (lparam.vkCode == 91 || lparam.vkCode == 164 || lparam.vkCode == 9 || lparam.vkCode == 115)
        {
            return 1;
        }
        else
        {
            return 0;
        }

    }
    return 0;
}

这里返回1代表消息终止,即不响应,返回0表示继续。这里的91,164,9,115即键盘的acsii值,表示屏蔽这些按键。

在此系统热键可以完全屏蔽掉了,但是这个方法却不能屏蔽ctrl+alt+del即弹出任务管理器的按键组合,这样就还是不能达到锁屏的效果
这里有个很简单的方法
FileStream  MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%system32   askmgr.exe"),
                                          FileMode.Open);
            byte[] Mybyte = new byte[(int)MyFs.Length];
            MyFs.Write(Mybyte, 0, (int)MyFs.Length);
即使用二进制流打开任务管理器,这样系统会认为任务管理器已经打开,使用ctrl+alt+del也就不会弹出任务管理器的窗口了,显然任务管理器已经打开,只不过在窗体界面是不会看见它罢了。
posted @ 2018-07-03 09:32  孤夏  阅读(1596)  评论(0编辑  收藏  举报