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

  

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 не обязателен. Также есть отдельные флаги для выключение компьютера (по умолчанию - перезагрузка) или завершения сетевого сеанса.

 

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

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

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

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