Electron开发在线考试系统:如何禁用Windows键及组合键防作弊?
禁用Windows键及Win组合键的可行方案
针对在线考试系统的防作弊需求,以下是几种能有效禁用Windows键、Win+PrtSc等组合键的技术方案:
1. 全局键盘钩子(Windows API)
这是最精准的拦截方式,能针对特定组合键做拦截,且可以临时生效,不影响系统全局设置。
- 核心思路:通过
SetWindowsHookEx注册全局低级键盘钩子,拦截WM_KEYDOWN或WM_SYSKEYDOWN消息,当检测到目标按键/组合键时,直接返回(IntPtr)1阻止消息传递给系统。 - 关键代码示例(C#):
private const int WM_KEYDOWN = 0x0100; private const int WM_SYSKEYDOWN = 0x0104; private const int VK_LWIN = 0x5B; private const int VK_RWIN = 0x5C; private const int VK_SNAPSHOT = 0x2C; private static IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) { int vkCode = Marshal.ReadInt32(lParam); // 拦截左右Windows键 if (vkCode == VK_LWIN || vkCode == VK_RWIN) return (IntPtr)1; // 拦截Win+PrtSc组合键 if ((GetKeyState(VK_LWIN) & 0x8000) != 0 && vkCode == VK_SNAPSHOT) return (IntPtr)1; } return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam); }
- 注意事项:钩子需在单独的DLL中实现(C++场景),C#可直接用
LowLevelKeyboardHook;程序必须以管理员权限运行,否则无法拦截系统级进程的按键消息。
2. 注册表临时修改(系统级禁用)
适合需要全局禁用的场景,但需重启生效,且考试结束后要恢复设置。
- 禁用Windows键:在
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout下新建二进制值Scancode Map,赋值为:00 00 00 00 00 00 00 00 03 00 00 00 00 00 5B E0 00 00 5C E0 00 00 00 00 - 禁用Win+PrtSc:该组合键触发系统截图,可通过注册表禁用截图功能——在
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer下新建DWORD值DisableSnippingTool,设为1,同时禁用Win+Shift+S等截图快捷键。 - 弊端:全局生效,影响所有用户;需重启系统才能生效/恢复,灵活性差。
3. 考试客户端独占模式+本地按键拦截
如果考试系统是桌面客户端,可让程序进入全屏独占模式,同时拦截客户端内的所有目标按键。
- WinForms实现:
private void Form_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; this.FormBorderStyle = FormBorderStyle.None; this.TopMost = true; } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { // 拦截Windows键 if (keyData == Keys.LWin || keyData == Keys.RWin) return true; // 拦截Win+PrtSc if ((keyData & Keys.LWin) == Keys.LWin && (keyData & Keys.PrintScreen) == Keys.PrintScreen) return true; return base.ProcessCmdKey(ref msg, keyData); } - WPF实现:
protected override void OnPreviewKeyDown(KeyEventArgs e) { if (e.Key == Key.LWin || e.Key == Key.RWin) { e.Handled = true; } if ((Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin)) && e.Key == Key.PrintScreen) { e.Handled = true; } base.OnPreviewKeyDown(e); } - 补充:同时需禁用任务管理器(Win+Ctrl+Esc),可临时修改注册表
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System下的DisableTaskMgr为1,考试结束后改回0。
4. Python快速实现(轻量客户端)
如果用Python开发考试客户端,可借助pynput库快速实现键盘拦截:
from pynput import keyboard def on_press(key): try: # 拦截左右Windows键 if key == keyboard.Key.cmd or key == keyboard.Key.cmd_r: return False # 拦截Win+PrtSc if (keyboard.KeyboardState([keyboard.Key.cmd]) or keyboard.KeyboardState([keyboard.Key.cmd_r])) and key == keyboard.Key.print_screen: return False except AttributeError: pass # 启动监听器 with keyboard.Listener(on_press=on_press) as listener: listener.join()
- 注意:程序必须以管理员权限运行,否则无法拦截系统级组合键。
核心注意事项
- 权限:所有全局拦截方案都需要管理员权限,否则会被系统进程绕过。
- 恢复机制:考试结束后必须恢复所有修改(注册表、钩子、任务管理器设置等),避免影响用户正常使用。
- 防作弊补充:单一按键拦截不足以完全防止作弊,建议结合屏幕监控、摄像头人脸识别、题目随机化、禁止切屏等手段。
内容的提问来源于stack exchange,提问作者Chey Sreylin
相关产品推荐
相关产品推荐

