因为捕获 CTRL-ALT-DEL 组合的是 Windows 的登录系统(因此用户应用程序无法访问它),您需要更改系统的键盘扫描码映射以忽略这些键中的至少一个.
首先您必须确保在您的计算机上自动登录,否则您可以登录。这也可以在注册表中完成。
然后是编辑扫描码映射的棘手部分。在 MSDN 你会找到一篇关于如何做的文章:https://msdn.microsoft.com/en-us/library/windows/hardware/jj128267%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
我发现这个 reg 文件应该禁用 CTRL + ALT + DELETE 但我还没有测试过
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,00,00,38,00,00,00,38,e0,\
00,00,00,00
请注意,这是非常危险的。使用 REG 文件和更改扫描码映射。我建议你在虚拟机中测试你的东西。
您还需要防止用户关闭计算机。这也在注册表中完成:
User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
Explorer]
Value Name: NoClose
Data Type: REG_DWORD (DWORD Value)
Value Data: (0 = shutdown enabled, 1 = shutdown disabled)
因此,为了关闭计算机,您的程序必须调用 ShutdownwindowsEx
function ExitWindows(iFlags: Integer): Boolean;
var
osVerInfo: TOSVersionInfo;
function SetPrivilege(sPrivilegeName: string; bEnabled: Boolean): Boolean;
var
TPPrev, TP: TTokenPrivileges;
Token: THandle;
dwRetLen: DWord;
begin
Result := False;
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token);
TP.PrivilegeCount := 1;
if (LookupPrivilegeValue(nil, PChar(sPrivilegeName), TP.Privileges[0].LUID)) then
begin
if (bEnabled) then
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
TP.Privileges[0].Attributes := 0;
dwRetLen := 0;
Result := AdjustTokenPrivileges(Token, False, TP, sizeof(TPPrev), TPPrev, dwRetLen);
end;
CloseHandle(Token);
end;
begin
Result := True;
osVerInfo.dwOSVersionInfoSize := sizeof(TOSVersionInfo);
if GetVersionEx(osVerInfo) then
case osVerInfo.dwPlatformId of
VER_PLATFORM_WIN32_WINDOWS:
if not ExitWindowsEx(iFlags, 0) then
Result := False; // handle errors...
VER_PLATFORM_WIN32_NT:
if SetPrivilege('SeShutdownPrivilege', True) then
begin
if not ExitWindowsEx(iFlags, 0) then
Result := False; // handle errors...
SetPrivilege('SeShutdownPrivilege', False)
end
else
Result := False; // handle errors...
else
Result := False;
end;
end;