Entwickler-Ecke

Windows API - PC herunterfahren


Apollo - Mo 07.01.08 13:34
Titel: PC herunterfahren
Hallo Delphianer,
gibt es eine Möglichkeit, den PC mit einem Click auf einem Button herunterzufahren?
Also das Beenden-Menü mit "Herunterfahren", "Neustart" und "Abmelden" aufzurufen?
Danke im voraus.


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 07.01.2008 um 13:07


jackle32 - Mo 07.01.08 13:42

Ja, das geht über den Aufruf eine Windowsfunktion mittels "ShellExecute".

Die Funktion die du Aufrufen musst heißt dann "Shutdown". Für die Parameter, die in den verschiedenen Fällen übergeben werden müssen einfach mal in der Windowshilfe danach suchen, steht da recht ausführliche drin.

Gruß Jack


Timosch - Mo 07.01.08 15:40

Arrgh! Man ruft keine Funktionen auf, indem man externe Programme startet. Ineffizient und schlechter Stil. Wenn ich will, dass ein Benutzer etwas eingibt, starte ich ja auch nicht den Notepad, sondern leg ein TMemo auf mein Formular. Außerdem existiert die shutdown.exe nicht auf jedem System.
Stattdessen ExitWindowsEx, such mal im Forum danach. AFAIK gibt es da auch einen Beitrag in der Library.
EDIT: http://www.delphi-library.de/viewtopic.php?t=8272
Hätte man aber auch sehr schnell selbst mit der Suche finden können.

Oder willst du das Dialogfeld "Herunterfahren" anzeigen lassen? Da musst du mit ShellExecute rundll32.exe mit irgendeinem Parameter aufrufen; ich weiß aber nicht, mit welchem.


COMMANDER86 - Mo 07.01.08 16:25

Herunterfahren: "rundll32.exe user,exitwindows"


Timosch - Mo 07.01.08 16:36

user profile iconCOMMANDER86 hat folgendes geschrieben:
Herunterfahren: "rundll32.exe user,exitwindows"

Nochmals: Nein!
Wenn schon, dann ruf einfach ExitWindows auf. rundll32.exe dient bloß als Umweg, z.B. über Batch-Dateien. Hier völlig unnötig. Aber ExitWindows ist AFAIK deprecated und von ExitWindowsEx abgelöst. Man ruft keine Programme auf, wenn es dafür auch eine API-Funktion gibt. Schließlich machen die aufgerufenen Programme auch nichts anderes, als die entsprechenden API-Funktionen aufzurufen.

Oder wolltest du auf meine Frage antworten
user profile iconTimosch hat folgendes geschrieben:
Oder willst du das Dialogfeld "Herunterfahren" anzeigen lassen? Da musst du mit ShellExecute rundll32.exe mit irgendeinem Parameter aufrufen; ich weiß aber nicht, mit welchem.

ExitWindows fährt den PC direkt runter. Ich suche den Aufruf für das Dialogfeld.


Apollo - Mo 07.01.08 18:14

Ich habe jetzt mal

Delphi-Quelltext
1:
ExitWindowsEx (Ewx_Shutdown, $FFFFFFFF);                    

und

Delphi-Quelltext
1:
ExitWindowsEX (Ewx_Reboot, $FFFFFFFF);                    

ausprobiert. Funktioniert leider nicht aber

Delphi-Quelltext
1:
ExitWindowsEX (Ewx_Logoff, $FFFFFFFF);                    

Hab Keine Ahnung warum :nixweiss:


Timosch - Mo 07.01.08 18:18

user profile iconApollo hat folgendes geschrieben:
Ich habe jetzt mal

Delphi-Quelltext
1:
ExitWindowsEx (Ewx_Shutdown, $FFFFFFFF);                    

und

Delphi-Quelltext
1:
ExitWindowsEX (Ewx_Reboot, $FFFFFFFF);                    

ausprobiert. Funktioniert leider nicht aber

Delphi-Quelltext
1:
ExitWindowsEX (Ewx_Logoff, $FFFFFFFF);                    

Hab Keine Ahnung warum :nixweiss:

In der Library stehts doch: Unter NT braucht der Aufruf u.U. bestimmte Privilegien, die man sich holen muss. Der Quelltext in, der dort weiter unten stand, erledigt das von alleine.

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:
uses
  Windows;

type
  TShutdownWindowsType = (swtShutdown, swtShutdownPowerOff, swtRestart, swtLogoff);

function ShutdownWindows (aType: TShutdownWindowsType): Boolean;

{...}

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

Und dann einfach nur ShutDownWindows mit entsprechenden Parametern aufrufen.


Yogu - Mo 07.01.08 18:20

Du musst noch eine kleine Windows-Versions-Überprüfung einfügen. Im DSDT [http://www.dsdt.info/tipps/?id=200] wird das schön erklärt. Oder du scrollst ein wenig nach oben, und schaust dir user profile iconTimoschs Post an. ;)


Timosch - Mo 07.01.08 18:26

user profile iconYogu hat folgendes geschrieben:
Du musst noch eine kleine Windows-Versions-Überprüfung einfügen. Im DSDT [http://www.dsdt.info/tipps/?id=200] wird das schön erklärt.

Erster! :D
Apollo: Siehe der obere Source, das erledigt der alles.


elundril - Mo 07.01.08 18:28

oder wenn du den lustigen dialog von windows selbst haben willst gibts in jedi eine lustige kompo dafür.

lg elundril


leseratte18 - Mi 16.01.08 17:23

wie stehts mit standby?