使用Win32应用程序在Windows 7中禁用CONTROL + ALT + DELETE和Windows(win)键

我正在编写一个像kiosk一样运行的应用程序,应该允许用户退出应用程序。 在Windows 7 ,当他按下Win键或CTRL + ALT + DELETE时 ,它会退出程序。 我需要以编程方式在Windows 7禁用Ctrl + ALT + DELETE组合键和Win键。

Alt + Tab也会切换出应用程序。 Ctrl + Esc是打开“开始”菜单的备用快捷方式。 Alt + Esc在正在运行的应用程序之间翻转。 有许多不同的键序列可以做到这一点; Windows是多任务操作系统的自然结果。

要解决此问题,您将不得不安装一个可以捕获这些任务键的低级键盘钩子。 钩子必须实现为DLL,它将监视用于切换任务的任何公共键序列。 每当它检测到其中一个序列时,它将忽略输入而不将其传递给钩链。 Paul DiLascia撰写了一篇文章,在2002年9月的MSDN杂志中解决了这个问题 。 您关心的部分从页面的中间开始,但为了方便起见我在这里重印了它,以获得语法高亮的乐趣:

TaskKeyHook.h:

 //////////////////////////////////////////////////////////////// // MSDN Magazine — September 2002 // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. // Compiles with Visual Studio 6.0 and Visual Studio .NET on Windows XP. // #define DLLIMPORT __declspec(dllimport) DLLIMPORT BOOL DisableTaskKeys(BOOL bEnable, BOOL bBeep); DLLIMPORT BOOL AreTaskKeysDisabled(); 

TaskKeyHook.cpp

 //////////////////////////////////////////////////////////////// // MSDN Magazine — September 2002 // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. // Compiles with Visual Studio 6.0 and Visual Studio .NET on Windows XP. // // This file implements the low-level keyboard hook that traps the task // keys. // #define _WIN32_WINNT 0x0500 // for KBDLLHOOKSTRUCT #include  // MFC core and standard components #define DLLEXPORT __declspec(dllexport) ////////////////// // App (DLL) object // class CTaskKeyHookDll : public CWinApp { public: CTaskKeyHookDll() { } ~CTaskKeyHookDll() { } } MyDll; //////////////// // The section is SHARED among all instances of this DLL. // A low-level keyboard hook is always a system-wide hook. // #pragma data_seg (".mydata") HHOOK g_hHookKbdLL = NULL; // hook handle BOOL g_bBeep = FALSE; // beep on illegal key #pragma data_seg () #pragma comment(linker, "/SECTION:.mydata,RWS") // tell linker: make it // shared ///////////////// // Low-level keyboard hook: // Trap task-switching keys by returning without passing along. // LRESULT CALLBACK MyTaskKeyHookLL(int nCode, WPARAM wp, LPARAM lp) { KBDLLHOOKSTRUCT *pkh = (KBDLLHOOKSTRUCT *) lp; if (nCode==HC_ACTION) { BOOL bCtrlKeyDown = GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) * 8) - 1); if ((pkh->vkCode==VK_ESCAPE && bCtrlKeyDown) || // Ctrl+Esc // Alt+TAB (pkh->vkCode==VK_TAB && pkh->flags & LLKHF_ALTDOWN) || // Alt+Esc (pkh->vkCode==VK_ESCAPE && pkh->flags & LLKHF_ALTDOWN)|| (pkh->vkCode==VK_LWIN || pkh->vkCode==VK_RWIN)) { // Start Menu if (g_bBeep && (wp==WM_SYSKEYDOWN||wp==WM_KEYDOWN)) MessageBeep(0); // only beep on downstroke if requested return 1; // gobble it: go directly to jail, do not pass go } } return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp); } ////////////////// // Are task keys disabled—ie, is hook installed? // Note: This assumes there's no other hook that does the same thing! // DLLEXPORT BOOL AreTaskKeysDisabled() { return g_hHookKbdLL != NULL; } ////////////////// // Disable task keys: install low-level kbd hook. // Return whether currently disabled or not. // DLLEXPORT BOOL DisableTaskKeys(BOOL bDisable, BOOL bBeep) { if (bDisable) { if (!g_hHookKbdLL) { g_hHookKbdLL = SetWindowsHookEx(WH_KEYBOARD_LL, MyTaskKeyHookLL, MyDll.m_hInstance, 0); } } else if (g_hHookKbdLL != NULL) { UnhookWindowsHookEx(g_hHookKbdLL); g_hHookKbdLL = NULL; } g_bBeep = bBeep; return AreTaskKeysDisabled(); } 

他还提供了禁用任务栏的示例代码(从而阻止Windows键显示“开始”菜单)以及使用这些库的完整示例应用程序。

至于阻止Ctrl + Alt + Del (安全注意序列或SAS),上述方法不起作用。 原因是操作系统将SAS生成的硬件中断与其他密钥分开,特别是为了防止程序挂钩序列和欺骗登录提示。 您无法使用键盘钩子禁用此function。 我上面链接的文章确实在顶部详细介绍了这个要求,但这些策略只是经过测试,而且很可能只适用于Windows XP。 本文提出的另一种方法是禁用任务管理器,但请注意,这不会阻止用户关闭系统等。 正确的方法是编写键盘驱动程序。

AFAIK,你不能在win32中捕获CTRL + ALT + DELETE键组合。 如果您愿意,有办法解决问题。

我认为这可以通过替换主Windows键盘驱动程序kbdclass.sys来实现。 应该可以在其内部处理按下Delete键,例如,当Ctrl和Alt键已经关闭时,避免进一步转移它。