Entwickler-Ecke

Windows API - wie kann ich Shutdown -r schicken ans Shell ???


ski20 - Di 03.03.09 16:09
Titel: wie kann ich Shutdown -r schicken ans Shell ???
Hi,

Wie kann ich Shutdown -r 60 bzw. Shutdown -s an der Betriebssystem ?? möglicheweise mit ShellExecute !

danke

Ski


Delete - Di 03.03.09 16:17

Wieso nicht einfach ExitWindowsEx [http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx] benutzen?


ski20 - Di 03.03.09 16:28

Hi DaddyH

hast du eine beispiel für mich wie die syntax sein könnte.


Timosch - Di 03.03.09 16:35

ExitWindowsEx alleine reicht nicht, da u.U. die Privilegien nicht vorhanden sind.
Aber schau mal hier [http://www.delphi-library.de/viewtopic.php?t=8272]. Da findest du folgenden Quelltext:

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 zum Thema, warum man nicht shutdown.exe verwenden soll, habe ich hier [http://www.delphi-forum.de/viewtopic.php?t=80511] mal was geschrieben:
user profile iconTimosch hat folgendes geschrieben:

Man ruft keine externen Programme auf, um Dinge durchzuführen, für die es API-Befehle gibt.
Wenn ich den Benutzer nach etwas frage, starte ich ja auch nicht den Notepad, lasse ihn den Text eingeben und abspeichern und lese die Datei aus, sondern verwende TEdit, InputBox oder ReadLn.
Sonst ergeben sich folgende Probleme:
1. fördert das die Abhängigkeit von externen Dateien, die u.U. gar nicht existieren. Wenn ich in meine Eingabeaufforderung eingebe "shutdown -s -f" kommt "Der Befehl "shutdown" ist entweder falsch geschrieben oder konnte nicht gefunden werden." Warum wohl? Weil ich Windows 2000 verwende...
2. kostet es Zeit und Ressourcen, weil der Rechner einen neuen Prozess starten muss. Fällt zwar nicht sehr ins Gewicht, ist aber vollkommen grundlos.
3., wie Luckie schon sagte, zwingt es den Benutzer, als Admin zu arbeiten.
Das geht jetzt an alle, die mit diesem Vorschlag (und ähnlichen) in solchen Threads immer wieder ankommen: Lasst das! Bitte! So gewöhnt man Anfängern gleich verheerende Fehler an...


ski20 - Di 03.03.09 16:59

Super vielen Dank.

Have a nice Day

Ski