Entwickler-Ecke

Windows API - Windows Shutdown funzt net,was ich falsch gemacht?


bluecat - Sa 08.11.03 01:27
Titel: Windows Shutdown funzt net,was ich falsch gemacht?
Hallo Leute!

Ich möchte per Knopfdruck Windows XP beenden und habe ich die folgende fkt verwendet. Leider machtr der gar net,kann jemand mir sagen,was ich falsch gemacht habe? (Delphi 7)

Danke im voraus!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
unit shutdownU;

interface

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

type
  TShutdownWindowsType = (swtShutdown, swtShutdownPowerOff, swtRestart, swtLogoff);
  TShutdown = class(TForm)
    ShutDown_Btn: TBitBtn;
    procedure ShutDown_BtnEnter(Sender: TObject);
    //function ShutdownWindows (aType: TShutdownWindowsType) :Boolean;
    procedure ShutDown_BtnClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Shutdown: TShutdown;

implementation

{$R *.dfm}

procedure TShutdown.ShutDown_BtnEnter(Sender: TObject);
begin
shutdown_btn.ShowHint:=true;
end;

function ShutdownWindows (aType: TShutdownWindowsType): Boolean;

const 
  cSE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
  cFlagValue: Array [TShutdownWindowsType] Of UINT = (EWX_SHUTDOWN,
   EWX_SHUTDOWN or EWX_POWEROFF, EWX_REBOOT, EWX_LOGOFF);

var 
  OSVersionInfo: TOSVersionInfo; 
  hToken: THandle;
  hProcess: THandle; 
  TokenPriv: TTokenPrivileges; 
  ReturnLength: DWORD;

begin 
  Result := False;

  // Die Windowsversion holen 
  OSVersionInfo.dwOSVersionInfoSize := SizeOf (OSVersionInfo);
  if not GetVersionEx (OSVersionInfo) then 
    Exit; 

  // Prüfen ob Windows NT 
  if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then 
    begin
      hProcess := GetCurrentProcess; 
      if not OpenProcessToken (hProcess, TOKEN_ADJUST_PRIVILEGES, hToken) then 
        Exit;

      if not LookupPrivilegeValue (nil, cSE_SHUTDOWN_NAME, TokenPriv.Privileges[0].Luid) then 
        Exit;

      TokenPriv.PrivilegeCount := 1
      TokenPriv.Privileges [0].Attributes := SE_PRIVILEGE_ENABLED;

      if not AdjustTokenPrivileges (hToken, False, TokenPriv, 0,
          PTokenPrivileges (nil)^, ReturnLength )
      then 
        Exit; 

      CloseHandle (hToken); 
    end

  ShutdownWindows := ExitWindowsEx (cFlagValue[aType], $FFFFFFFF);
end;

procedure TShutdown.ShutDown_BtnClick(Sender: TObject);
begin
ShutdownWindows(EWX_POWEROFF);
end;

end.

:(

Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.


elbrand - Sa 08.11.03 14:39

also ich benutze folgende funktion, die muesste eigentlich gehen.
ich glaube nur leider, dass sie identisch mit deiner ist - vielleicht findest du ja trotzdem einen unterschied. leider sitze ich z.Z. nur vor einem WinNT-rechner, sobald ich wieder vor einer xp-kiste sitze probier' ich's nochmal aus.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
{
so rufst du sie, je , nachdem, was du machen willst, auf:

   ShutdownWindows(swtShutdown);
   ShutdownWindows(swtShutdownPowerOff);
   ShutdownWindows(swtRestart);
   ShutdownWindows(swtLogoff);

}


function ShutdownWindows (aType: TShutdownWindowsType): Boolean;

const
  cSE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
  cFlagValue: Array [TShutdownWindowsType] Of UINT = (
      EWX_SHUTDOWN, EWX_SHUTDOWN or EWX_POWEROFF, EWX_REBOOT, EWX_LOGOFF
    );

var
  OSVersionInfo: TOSVersionInfo;
  hToken: THandle;
  hProcess: THandle;
  TokenPriv: TTokenPrivileges;
  ReturnLength: DWORD;

begin
  Result := False;

  // Die Windowsversion holen
  OSVersionInfo.dwOSVersionInfoSize := SizeOf (OSVersionInfo);
  if not GetVersionEx (OSVersionInfo) then
    Exit;

  // Prüfen ob Windows NT
  if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
    begin
      hProcess := GetCurrentProcess;
      if not OpenProcessToken (hProcess, TOKEN_ADJUST_PRIVILEGES, hToken) then
        Exit;

      if not LookupPrivilegeValue (nil, cSE_SHUTDOWN_NAME, TokenPriv.Privileges[0].Luid) then
        Exit;

      TokenPriv.PrivilegeCount := 1;
      TokenPriv.Privileges [0].Attributes := SE_PRIVILEGE_ENABLED;

      if not AdjustTokenPrivileges (
          hToken, False, TokenPriv, 0,
          PTokenPrivileges (nil)^, ReturnLength
        )
      then
        Exit;

      CloseHandle (hToken);
    end;

  ShutdownWindows := ExitWindowsEx (cFlagValue [aType], $FFFFFFFF);
end;


Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.


jones - Sa 23.04.05 12:51

hmm, wenn ich die obrige funktion verwende, dann sagt delphi, dass es "PTokenPrivileges" an der stelle

Delphi-Quelltext
1:
2:
3:
4:
if not AdjustTokenPrivileges (
 hToken, False, TokenPriv, 0,
 PTokenPrivileges (nil)^, ReturnLength
)
nicht kennt.

muss ich dafür noch irgendwas deklarieren?

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


feuerwaran - So 24.04.05 19:55

wie wärs mit nem


Delphi-Quelltext
1:
ShellExecute(Application.Handle, 'open''shutdown -s'nilnil, SW_SHOW);                    


das ist ne billigvariante :D , aber müßte gehen.

vorher noch ein


Delphi-Quelltext
1:
uses shellapi;                    


Delete - Mo 25.04.05 08:59

user profile iconfeuerwaran hat folgendes geschrieben:
wie wärs mit nem


Delphi-Quelltext
1:
ShellExecute(Application.Handle, 'open''shutdown -s'nilnil, SW_SHOW);                    


das ist ne billigvariante :D , aber müßte gehen.

vorher noch ein


Delphi-Quelltext
1:
uses shellapi;                    


das funktioniert doch nur unter WindowsXP, oder?


jones - Mo 25.04.05 15:21

ja, aber ich hab die shutdown.exe unter 2k einfach nach winnt\system32 kopiert und so gehts auch :D


Delete - Mo 25.04.05 15:30

user profile iconjones hat folgendes geschrieben:
ja, aber ich hab die shutdown.exe unter 2k einfach nach winnt\system32 kopiert und so gehts auch :D


und woher willst du die Datei unter Windows 2000 nehmen, wenn man kein WinXP hat?


Karlson - Mo 25.04.05 15:55

Indem man die shutdownexe hinten an die Exe ranhängt (ich weiss, is illegal...).


Delete - Mo 25.04.05 16:17

user profile iconKarlson hat folgendes geschrieben:
(ich weiss, is illegal...).


genau das ist es und deshalb ist die Lösung mit der shutdown.exe Schrott :!:


feuerwaran - So 01.05.05 17:39

Das ist bestimmt kein Schrott.

1. Wer XP benutzt, kommt diese Variante einfach vor.
2. In dem Resource-Kit von Microsoft ist die shutdown.exe enthalten. Wer diese Erwirbt macht sich nicht strafbar, wenn er shutdown.exe benutzt.


Heiko - So 01.05.05 18:20

Also ich verwende immer


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure ExitWindows;
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 // Windows NT
   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);
  end;
 ExitWindowsEx(EWX_SHUTDOWN, 0)
end;


Diese Variante hat bisher auf jedem Windows funktioniert, also auch unter Win XP SP2.


Delete - So 01.05.05 18:55

user profile iconfeuerwaran hat folgendes geschrieben:
1. Wer XP benutzt, kommt diese Variante einfach vor.
2. In dem Resource-Kit von Microsoft ist die shutdown.exe enthalten. Wer diese Erwirbt macht sich nicht strafbar, wenn er shutdown.exe benutzt.

Das mag ja alles sein, aber die Funktion "ExitWindowsEx" ist zum Herunterfahren, Neustarten, usw. gedacht. Unter NT-Systemen ist es schlicht nur eine Frage der Rechte. Hat man das mal kapiert, kann man eine Funktion benutzen, die von Windows 95 bis XP (2003 Server vermutlich auch) funktioniert, und für die man kein externes Programm benötigt.


feuerwaran - So 08.05.05 00:05

Ich wollte doch mal nur kreativ sein und habe für das geschilderte Problem eine Lösung vorgeschlagen. Kann sein das es für manche Leute nicht zutrifft, aber es als Schrott zu bezeichnen finde ich nicht gerade logisch.


Delete - So 08.05.05 10:17

Mag sein, dass derjenige, der es als Schrott bezeichnet hat, etwas übertrieb. Aber ich persönlich halte deine Lösung trotzdem nicht für gut. Kreativ? Meinetwegen. Gut? Nein. Wie gesagt: Besitzer von 95/98/ME gucken in die Röhre und müssten sich theoretisch erst dieses Tool besorgen. Und dann wäre noch die Frage, ob es überhaupt auf 9x-Rechnern läuft, was ich bezweifle. Und wenn man dann noch bedenkt, dass es eine im System eingebaute Funktion gibt, die von 95 bis ... funktioniert, dann weißt du auch selbst, warum deine Lösung nicht gut ist.

Dass man von einigen vllt. etwas härter kritisiert ist, damit muss man leben (können). Nicht alles immer gleich so persönlich nehmen.