Содержание материала

  

exitkernel очень радикальный способ потому что не сохраняются настройки рабочего стола, ini файлы и другие установки, зато быстро

 Есть способ намного лучше: ф-ия SHExitWindowsEx из shell32.dll

С неё всё good. Это запуск из-под WinExec()

Code:

function GetWinVersion: String;

var

  VersionInfo : TOSVersionInfo;

  OSName      : String;

begin

  // устанавливаем размер записи

  VersionInfo.dwOSVersionInfoSize := SizeOf( TOSVersionInfo );

 

  if Windows.GetVersionEx( VersionInfo ) then

     begin

        with VersionInfo do

        begin

           case dwPlatformId of

              VER_PLATFORM_WIN32s   : OSName := 'Win32s';

              VER_PLATFORM_WIN32_WINDOWS : OSName := 'Windows 95';

              VER_PLATFORM_WIN32_NT      : OSName := 'Windows NT';

           end; // case dwPlatformId

           Result := OSName + ' Version ' + IntToStr( dwMajorVersion ) + '.' + IntToStr( dwMinorVersion ) +

                     #13#10' (Build ' + IntToStr( dwBuildNumber ) + ': ' + szCSDVersion + ')';

        end; // with VersionInfo

     end // if GetVersionEx

  else

     Result := '';

end;

 

procedure ShutDown;

const

SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';   // Borland forgot this declaration

var

hToken       : THandle;

tkp          : TTokenPrivileges;

tkpo         : TTokenPrivileges;

zero         : DWORD;

begin

if Pos( 'Windows NT', GetWinVersion) = 1 then // we've got to do a whole buch of things

    begin

       zero := 0;

       if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then

          begin

            MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );

            Exit;

          end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)

       if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then

          begin

            MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );

            Exit;

          end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)

 

 

       // SE_SHUTDOWN_NAME

       if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[ 0 ].Luid ) then

          begin

             MessageBox( 0, 'Exit Error', 'LookupPrivilegeValue() Failed', MB_OK );

             Exit;

          end; // if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[0].Luid )

       tkp.PrivilegeCount := 1;

       tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED;

 

       AdjustTokenPrivileges( hToken, False, tkp, SizeOf( TTokenPrivileges ), tkpo, zero );

       if Boolean( GetLastError() ) then

          begin

             MessageBox( 0, 'Exit Error', 'AdjustTokenPrivileges() Failed', MB_OK );

             Exit;

          end // if Boolean( GetLastError() )

       else

          ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );

     end // if OSVersion = 'Windows NT'

  else

     begin // just shut the machine down

       ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );

     end; // else

end;

 

Программно же только с получением привелегии.

Замечу также что флаг EWX_FORCE необходим только для принудительного завершения при выдаче каких либо сообщений или модальных окон, что воспрепятствует завершению, например, "К компьютеру подключены пользователи. Данные могут быть утярены. Вы хотите завершить работу?" или сообщение, которое автор указал в вопросе.

Если нет таких сообщений EWX_FORCE не обязателен. Также есть отдельные флаги для выключение компьютера (по умолчанию - перезагрузка) или завершения сетевого сеанса.

 


 

Code:

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;

 

 

// Parameters for MyExitWindows()


 

Code:

program Shutdown;

{$APPTYPE CONSOLE}

 

uses

SysUtils,

Windows;

 

// Shutdown Program

// (c) 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:      dont 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 dont 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.

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить