一般來說會用到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也就不會彈出任務管理器的窗口了,顯然任務管理器已經打開,只不過在窗體界面是不會看見它罷了。
