Как выключить, перезагрузить или завершить Windows?

Материал из DRKB

Как выключить, перезагрузить или завершить Windows?[править | править код]

function MyExitWindows(RebootParam: Longword): 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;

// Example to shutdown Windows:

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyExitWindows(EWX_POWEROFF or EWX_FORCE);
end;

// Example to reboot Windows:

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyExitWindows(EWX_REBOOT or EWX_FORCE);
end;




2. Console Shutdown Demo[править | править код]

program Shutdown;
{$APPTYPE CONSOLE}

uses 
  SysUtils, 
  Windows; 

// Shutdown Program 
// (c) 2000 NeuralAbyss Software 
// www.neuralabyss.com 

var 
  logoff: Boolean = False; 
  reboot: Boolean = False; 
  warn: Boolean = False; 
  downQuick: Boolean = False; 
  cancelShutdown: Boolean = False; 
  powerOff: Boolean = False; 
  timeDelay: Integer = 0; 

function HasParam(Opt: Char): Boolean; 
var 
  x: Integer; 
begin 
  Result := False; 
  for x := 1 to ParamCount do 
    if (ParamStr(x) = '-' + opt) or (ParamStr(x) = '/' + opt) then Result := True; 
end; 

function GetErrorstring: string; 
var 
  lz: Cardinal; 
  err: array[0..512] of Char; 
begin 
  lz := GetLastError; 
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil); 
  Result := string(err); 
end; 

procedure DoShutdown; 
var 
  rl, flgs: Cardinal; 
  hToken: Cardinal; 
  tkp: TOKEN_PRIVILEGES; 
begin 
  flgs := 0; 
  if downQuick then flgs := flgs or EWX_FORCE; 
  if not reboot then flgs := flgs or EWX_SHUTDOWN; 
  if reboot then flgs := flgs or EWX_REBOOT; 
  if poweroff and (not reboot) then flgs := flgs or EWX_POWEROFF; 
  if logoff then flgs := (flgs and (not (EWX_REBOOT or EWX_SHUTDOWN or EWX_POWEROFF))) or 
      EWX_LOGOFF; 
  if Win32Platform = VER_PLATFORM_WIN32_NT then 
  begin 
    if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, 
      hToken) then 
      Writeln('Cannot open process token. [' + GetErrorstring + ']') 
    else 
    begin 
      if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then 
      begin 
        tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; 
        tkp.PrivilegeCount           := 1; 
        AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl); 
        if GetLastError <> ERROR_SUCCESS then 
          Writeln('Error adjusting process privileges.'); 
      end 
      else 
        Writeln('Cannot find privilege value. [' + GetErrorstring + ']'); 
    end; 
    {   if CancelShutdown then 
          if AbortSystemShutdown(nil) = False then 
            Writeln(\'Cannot abort. [\' + GetErrorstring + \']\') 
          else 
           Writeln(\'Cancelled.\') 
       else 
       begin 
         if InitiateSystemShutdown(nil, nil, timeDelay, downQuick, Reboot) = False then 
            Writeln(\'Cannot go down. [\' + GetErrorstring + \']\') 
         else 
            Writeln(\'Shutting down!\'); 
       end; 
    } 
  end; 
  //     else begin 
  ExitWindowsEx(flgs, 0); 
  //     end; 
end; 

begin 
  Writeln('Shutdown v0.3 for Win32 (similar to the Linux version)'); 
  Writeln('(c) 2000 NeuralAbyss Software. All Rights Reserved.'); 
  if HasParam('?') or (ParamCount = 0) then 
  begin 
    Writeln('Usage:    shutdown [-akrhfnc] [-t secs]'); 
    Writeln('                  -k:      do not really shutdown, only warn.'); 
    Writeln('                  -r:      reboot after shutdown.'); 
    Writeln('                  -h:      halt after shutdown.'); 
    Writeln('                  -p:      power off after shutdown'); 
    Writeln('                  -l:      log off only'); 
    Writeln('                  -n:      kill apps that do not want to die.'); 
    Writeln('                  -c:      cancel a running shutdown.'); 
  end 
  else 
  begin 
    if HasParam('k') then warn := True; 
    if HasParam('r') then reboot := True; 
    if HasParam('h') and reboot then 
    begin 
      Writeln('Error: Cannot specify -r and -h parameters together!'); 
      Exit; 
    end; 
    if HasParam('h') then reboot := False; 
    if HasParam('n') then downQuick := True; 
    if HasParam('c') then cancelShutdown := True; 
    if HasParam('p') then powerOff := True; 
    if HasParam('l') then logoff := True; 
    DoShutdown; 
  end; 
end.



Source: Взято с http://delphiworld.narod.ru
ID: 01670


функции ExitWindows/ExitWindowsEx[править | править код]

Для выполнения перезагрузки/выключения предназначены функции ExitWindows/ExitWindowsEx

ExitWindows[править | править код]

Описание
Function ExitWindows(Reserved: DWord; ReturnCode: Word): Bool;
Инициирует стандартную процедуру завершения работы с Windows. Все прикладные задачи должны подтвердить завершение работы Windows. Вызывает функцию 4CH прерывания 21H DOS.
Параметры
  • Reserved: Установлен в нуль.
  • ReturnCode: Значение, передаваемое в DOS (в регистре AL).
Возвращаемое значение
Нуль, если одна или несколько задач отказываются завеpшить работу.
Примеры использования
ExitWindows(EWX_LOGOFF,0); - завершение сеанса
ExitWindows(EWX_SHUTDOWN,0); - выключение компьютера
ExitWindows(EWX_REBOOT,0); - перезагрузка
Флаги EWX_FORCE, EWX_POWEROFF и  EWX_FORCEIFHUNG могут комбинироваться к нужному действию.


ExitWindowsEx[править | править код]

Функция ExitWindowsEx() представляет собой расширенный вариант ExitWindows().

Описание
BOOL ExitWindowsEx( UINT uFlags, DWORD dwReserved, );
Функция ExitWindowsEx перезагружает(restart) или выключает систему (shutdown), а также может завершить сессию для текущего пользователя(log off).
Параметры
  • uFlags -- флаг завершения работы, может принимать следущие значения:
    • EWX_LOGOFF завершает сессию текущего пользователя.
    • EWX_POWEROFF выключает питание компьютера(компьютер должен поддерживать данную функцию).
    • EWX_REBOOT перезагружает систему.
    • EWX_SHUTDOWN завершает работу компьютера до того места, где он может быть безопасно выключен: сброшены все файловые буферы на диск, завершает работу всех процессов.
  • dwReserved - Зарезервировано для последующих нужд, параметр игнорируется.
Возвращаемое значение
Не ноль если всё прошло успешно
Пример использования
ExitWindowsEx(EWX_SHUTDOWN, 0);
Остальные примеры смотри в описании первой функции.

Вышеописанные примеры действительны только для w9x/Me.

Дело в том, что, чтобы выполнить функцию в NT ОС, нужно получить права на выполнение этой функции. Сделать это можно через AdjustTokenPriviligies. С помощью нижеприведённой функции можно получить любую привилегию, в т.ч. и привилегию SeShutdownPrivilege, которая нужна для разрешения функции ExitWindows(Ex)


function SetPrivilege(aPrivilegeName: String; aEnabled: 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(aPrivilegeName), TP.Privileges[0].LUID)) then 
  begin 
   if aEnabled 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;


Пример использования для среды NT:

SetPrivilege('SeShutdownPrivilege', True);
ExitWindowsEx(EWX_SHUTDOWN, 0);


Author: Song
Source: Взято из http://forum.sources.ru
ID: 01671