Ja w jednym programie rozwiązałem to tak i jak widac dla Windowsa 98 trzeba inaczej,
ale kod ktory jest dla Windowsów NT mi pod Windows XP Home z SP 2 - działa dobrze.
Nie wiem jak będzie pod Windowsami 64 bitowymi, ale może i również wtedy zadziała.
function MyExitWindows(RebootParam: DWord): Boolean;
var
TTokenHd : THandle;
TTokenPvg : TTokenPrivileges;
cbtpPrevious : DWORD;
rTTokenPvg : TTokenPrivileges;
pcbtpPreviousRequired : DWORD;
tpResult : boolean;
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
tpResult := OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TTokenHd);
if tpResult then
begin
tpResult := LookupPrivilegeValue(nil,
SE_SHUTDOWN_NAME, TTokenPvg.Privileges[0].Luid);
TTokenPvg.PrivilegeCount := 1;
TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
cbtpPrevious := SizeOf(rTTokenPvg);
pcbtpPreviousRequired := 0;
if tpResult then
Windows.AdjustTokenPrivileges(TTokenHd,
False, TTokenPvg, cbtpPrevious, rTTokenPvg, pcbtpPreviousRequired);
end;
end;
Result := ExitWindowsEx(RebootParam, 0);
end;
procedure TurnOffComputer;
var
OS : TOsVersionInfo;
begin
OS.dwOSVersionInfoSize := SizeOf(os);
GetVersionEx(os);
case os.dwPlatformId of
VER_PLATFORM_WIN32_WINDOWS:
begin
ShellExecute(Application.Handle, 'open',
'rundll32.exe', 'user,ExitWindows', nil, SW_HIDE);
end;
VER_PLATFORM_WIN32_NT:
begin
MyExitWindows(EWX_POWEROFF or EWX_FORCE);
end;
end;
end;