Solved

ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

Posted on 2001-06-17
7
2,699 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

740 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