禁用系統熱鍵(包括禁止使用任務管理器)

通常來講會用到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就好了。ui

再引用一個獲取進程塊指針的方法spa

[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);

聲明一個指向執行函數的函數指針:code

private HookHandlerDelegate proc;

構造鉤子:blog

        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值,表示屏蔽這些按鍵。it

在此係統熱鍵能夠徹底屏蔽掉了,可是這個方法卻不能屏蔽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也就不會彈出任務管理器的窗口了,顯然任務管理器已經打開,只不過在窗體界面是不會看見它罷了。
相關文章
相關標籤/搜索