Solved

ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

Posted on 2001-06-17
7
2,636 Views
Last Modified: 2012-08-14
HI all

I have made a computer shutting program
but program not work in Win2000

this line:
ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

How i changed that?

Thanks
Janozzy
0
Comment
Question by:janozzy
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 22

Accepted Solution

by:
Mohammed Nasman earned 100 total points
ID: 6199519
Hello

  In win2k you need to have privileges for shutdown the computer, try this example and you can shutdown the computer in any version of windows, it will detect ur win version and than shutdown the pc, I got it from delphi3000 site.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function GetWinVersion: String;
var
   VersionInfo : TOSVersionInfo;
   OSName      : String;
begin
   // set the size of the record
   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;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShutDown;
end;

end.
0
 
LVL 17

Expert Comment

by:inthe
ID: 6199542
Hi,
you need the correct privileges to do it in nt/win2k
try using a procedure like this instead:

function srExitWindows(const aFlags: Word): Boolean;
var
  vi: TOSVersionInfo;
  hToken: THandle;
  tp: TTokenPrivileges;
  h: DWord;
begin
  vi.dwOsVersionInfoSize := SizeOf(vi);
  GetVersionEx(vi);
  if vi.dwPlatFormId = VER_PLATFORM_WIN32_NT then
  begin
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
hToken);
    LookUpPrivilegeValue(nil, 'SeShutDownPrivilege',
tp.Privileges[0].Luid);
    tp.PrivilegeCount := 1;
    tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    h := 0;
    AdjustTokenPrivileges(hToken, False, tp, 0,
PTokenPrivileges(nil)^, h);
    CloseHandle(hToken);
    Result := ExitWindowsEx(aFlags, 0);
  end
  else
    Result := ExitWindowsEx(aFlags, 0);
end;
0
 
LVL 17

Expert Comment

by:inthe
ID: 6199545
had the page open a bit long i think ;-)
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 20

Expert Comment

by:Madshi
ID: 6199631
Hi Janozzy,

two things:

(1) You're using ExitWindowsEx incorrectly. The second parameter is reserved and must be 0. You have to give in all flags into the first parameter like this:

ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE, 0);

(2) In NT based systems you need a special privilege to be enabled. I hate these privileges and that you always have to care about them. So I've written a little function, which I execute in all my projects, which simply enabled all available privileges. You can safely call this function in win9x, too. There is simply doesn't do anything:

procedure EnableAllPrivileges;
var c1, c2 : dword;
    ptp    : PTokenPrivileges;
    i1     : integer;
begin
  if OpenProcessToken(windows.GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, c1) then
    try
      c2 := 0;
      GetTokenInformation(c1, TokenPrivileges, nil, 0, c2);
      if c2 <> 0 then begin
        ptp := AllocMem(c2);
        if GetTokenInformation(c1, TokenPrivileges, ptp, c2, c2) then begin
          for i1 := 0 to integer(ptp^.PrivilegeCount) - 1 do
            ptp^.Privileges[i1].Attributes := ptp^.Privileges[i1].Attributes or SE_PRIVILEGE_ENABLED;
          AdjustTokenPrivileges(c1, false, ptp^, c2, PTokenPrivileges(nil)^, cardinal(pointer(nil)^));
        end;
        FreeMem(ptp);
      end;
    finally CloseHandle(c1) end;
end;

Regards, Madshi.
0
 

Author Comment

by:janozzy
ID: 6199656
MNASMAN : Your code don't work in 2000 and 98 give Msgsrv32 error.
Other answers not tested yet.

Thanks all

Janozzy
0
 
LVL 22

Expert Comment

by:Mohammed Nasman
ID: 6199679
Janozzy, i have win2000 and i test it there, it shutdown my computer while i tested and i back and rewrite it again, lol
0
 

Author Comment

by:janozzy
ID: 6199813
hi all
i found working code :

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


//
// iFlags:
//
//  one of the following must be
//  specified
//
//   EWX_LOGOFF
//   EWX_REBOOT
//   EWX_SHUTDOWN
//
//  following attributes may be
//  combined with above flags
//
//   EWX_POWEROFF
//   EWX_FORCE    : terminate processes
//
function WinExit (iFlags: integer) : Boolean;
begin
 result := true;
 if SetPrivilege ('SeShutdownPrivilege', true) then
 begin
   if (not ExitWindowsEx (iFlags, 0)) then
   begin
     // handle errors...
     result := False
   end;
   SetPrivilege ('SeShutdownPrivilege', False)
 end
 else
 begin
   // handle errors...
   result := False
 end
end;

Thanks all answers.
I give points to Mnasman for his hard work:)
0

Featured Post

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question