Mira a ver si te funciona, la verdad no he tenido ocasión de probarlo.
Código:
var
hToken: THANDLE;
tkp, tkDumb: TTokenPrivileges;
DumbInt: DWord;
begin
FillChar(tkp, sizeof(tkp), 0);
// Obtengo el token de este proceso
if not (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or
TOKEN_QUERY, hToken)) then
raise Exception.create('OpenProcessToken falló con el código ' +
inttostr(GetLastError));
// Obtengo el LUID para provilegios de Shutdown
LookupPrivilegeValue(nil, pchar('SeShutdownPrivilege'),
tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
// Obtengo el privilegio de shutdown para este proceso
AdjustTokenPrivileges(hToken, false, tkp, sizeof(tkDumb), tkDumb,
DumbInt);
// No puedo testear el valor de retorno de AdjustTokenPrivileges
if GetLastError <> ERROR_SUCCESS then
raise Exception.create('AdjustTokenPrivileges falló con el código ' +
inttostr(GetLastError));
// apago el sistema, todas las aplicaciones se cerrarán
if not ExitWindowsEx(EWX_POWEROFF, 0) then
raise Exception.create('ExitWindowsEx falló con el código ' +
inttostr(GetLastError));
end;
Un Saludo