我不能用c#禁用Windows Key
本文关键字:Windows Key 禁用 不能 | 更新日期: 2023-09-27 17:50:11
我用的是Windows 8。我试着用c#禁用Windows Key,就像这个例子http://tamas.io/c-disable-ctrl-alt-del-alt-tab-alt-f4-start-menu-and-so-on/。没有错误,但是Windows Key没有被禁用。如何禁用Windows密钥与c# ?
这是我的代码。
namespace TestDisable
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId);
[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int UnhookWindowsHookEx(int hHook);
public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("user32", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
public const int WH_KEYBOARD_LL = 13;
/*code needed to disable start menu*/
[DllImport("user32.dll")]
private static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
public static int intLLKey;
public int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool blnEat = false;
try
{
switch (wParam)
{
case 256:
case 257:
case 260:
case 261:
//Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key,
blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) // alt+tab
| ((lParam.vkCode == 27) && (lParam.flags == 32)) // alt+esc
| ((lParam.vkCode == 27) && (lParam.flags == 0)) // ctrl+esc
| ((lParam.vkCode == 91) && (lParam.flags == 1)) // left winkey
| ((lParam.vkCode == 92) && (lParam.flags == 1))
| ((lParam.vkCode == 73) && (lParam.flags == 0));
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
if (blnEat == true)
{
return 1;
}
else
{
return CallNextHookEx(0, nCode, wParam, ref lParam);
}
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
您没有执行任何错误检查。在编辑中添加代码来捕获Win32函数引发的异常。但是Win32函数不会引发异常。相反,它们通过返回值传达成功和失败。
在这种情况下,intLLKey
被返回为0
。这表示失败。钓钩没有挂好。让我们添加一些错误检查:
intLLKey = SetWindowsHookEx(...);
if (intLLKey == 0)
throw new Win32Exception();
现在你会看到一个异常伴随着文本:
无法找到指定的模块。
这是ERROR_MOD_NOT_FOUND
。据推测,这是因为您提供的模块句柄未被识别为与您传递的钩子进程函数指针相关联。这是托管程序集的一个常见问题,其中互操作委托是在运行时动态创建的。
这里有一个可能的解决方案。首先,修复你的p/invoke声明:
public delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hHook);
[DllImport("user32", EntryPoint = "CallNextHookEx", SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
然后获得模块句柄并像这样调用SetWindowsHookEx
:
using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(curModule.ModuleName), 0);
}
if (intLLKey.ToInt64() == 0)
{
throw new Win32Exception();
}
您还必须修复由于我所做的所有类型更改而导致的许多编译错误,这些错误主要与使用IntPtr
来处理指针大小的句柄值有关。即HHOOK
。当调用CallNextHookEx
时,还必须传递intLLKey
。通过这些更改,您的代码将挂钩键盘事件。下面的内容:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hHook);
[DllImport("user32", EntryPoint = "CallNextHookEx", SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
public const int WH_KEYBOARD_LL = 13;
/*code needed to disable start menu*/
[DllImport("user32.dll")]
private static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
public static IntPtr intLLKey;
public IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool blnEat = false;
try
{
switch (wParam.ToInt64())
{
case 256:
case 257:
case 260:
case 261:
//Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key,
blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) // alt+tab
| ((lParam.vkCode == 27) && (lParam.flags == 32)) // alt+esc
| ((lParam.vkCode == 27) && (lParam.flags == 0)) // ctrl+esc
| ((lParam.vkCode == 91) && (lParam.flags == 1)) // left winkey
| ((lParam.vkCode == 92) && (lParam.flags == 1))
| ((lParam.vkCode == 73) && (lParam.flags == 0));
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
if (blnEat == true)
{
return (IntPtr)1;
}
else
{
return CallNextHookEx(intLLKey, nCode, wParam, ref lParam);
}
}
private void button1_Click(object sender, EventArgs e)
{
using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(curModule.ModuleName), 0);
}
if (intLLKey.ToInt64() == 0)
{
throw new Win32Exception();
}
}
}
这个故事的寓意?检查错误