Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi windows herunterfahren zusammengefaßt (https://www.delphipraxis.net/107402-windows-herunterfahren-zusammengefasst.html)

Marco Steinebach 27. Jan 2008 10:32


windows herunterfahren zusammengefaßt
 
Hallo Leute,
ich hab jetzt 'ne ganze Weile im Forum und Internet gewühlt, und mal alles zusammengetragen, was es so zum Windows Herunterfahren so gab.
Hier ist das Endresultat - aber ich hab noch eine Frage dazu:
Delphi-Quellcode:
// ein typ, der die parameter, die MyExitWindows übergeben werden können festlegt

  TExit = (EW_Garnicht, EW_Neustart, EW_Abmelden, EW_Herunterfahren, EW_Ruhezustand, EW_Standby);
// ;-) der EW_Garnicht kann auch weggelassen werden...

// unter Win NT/2000/xp/vista braucht man priviligien zum herunterfahren...
// die hab ich, zum besseren verständnis, ausgelagert.
procedure GetShutdownPrivileges;
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 or TOKEN_QUERY, hToken);
    // der Forums-Code von DoctorD hier um TOKEN_QUERY ergänzt...
    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;
end;

procedure MyExitWindows (E: TExit);
begin
  if e = EW_Garnicht then exit;
  GetShutdownPrivileges;
  if E = EW_herunterfahren then
    ExitWindowsEx(EWX_ShutDown or EWX_FORCEIFHUNG, 0);
  if E = EW_Ruhezustand then
    SetSystemPowerState(false, true);
  if E = EW_Standby then
    SetSystemPowerState(true, true);
  if E = EW_Abmelden then
    ExitWindowsEx(EWX_LOGOFF, 0);
  if E = EW_Neustart then
    ExitWindowsEx(EWX_REBOOT,0);
end;
so weit, so gut.
eine Frage: wozu benötigt man EWX_POWEROFF - mir ist der Unterschied zu EWX_SHUTDOWN beim besten willen nicht klar.

Hat jemand verbesserungsvorschläge, damit das Ding allgemeinültig und funktionell vielleicht noch besser wird?

Viele Grüße
Marco

toms 27. Jan 2008 10:36

Re: windows herunterfahren zusammengefaßt
 
Zitat:

EWX_LOGOFF
Alle Prozesse des Benutzers werden beendet, danach wird der Benutzer abgemeldet.

EWX_POWEROFF
Fährt Windows herunter und setzt den Computer in den StandBy-Modus, sofern von der Hardware unterstützt.

EWX_REBOOT
Fährt Windows herunter und startet es neu.

EWX_SHUTDOWN
Fährt Windows herunter.

EWX_FORCE
Die aktiven Prozesse werden zwangsweise und ohne Rückfrage beendet.

EWX_FORCEIFHUNG
(Nur Windows 2000) Die aktiven Prozesse werden aufgefordert, sich selbst zu beenden und müssen dies bestätigen. Reagieren sie nicht, werden sie zwangsweise beendet.
http://www.microsoft.com/germany/msd....mspx?mfr=true

Vorschlag: EWX_FORCE und EWX_FORCEIFHUNG implementieren. (optionaler Parameter)

MrKnogge 27. Jan 2008 10:40

Re: windows herunterfahren zusammengefaßt
 
Gibt es "EWX_FORCEIFHUNG" nur für Windows2000 oder ab Windows2000 ?
Weil dann bliebe mir ja sonst nur "EWX_FORCE", was mir eigentlich zu "hart" wäre :?

Marco Steinebach 27. Jan 2008 12:28

Re: windows herunterfahren zusammengefaßt
 
Hallo,
Zitat:

Zitat von MrKnogge
Gibt es "EWX_FORCEIFHUNG" nur für Windows2000 oder ab Windows2000?

nein, ;-), ab Windows 2000.

Also hier die zweite Version:
Code:
procedure MyExitWindows (E: TExit; force: boolean);
var
  vi: TOSVersionInfo;
  flag: integer;
begin
  if e = EW_Garnicht then exit;
  flag := 0;
  vi.dwOSVersionInfoSize:=SizeOf(vi);
  GetVersionEx (vi);
  if vi.dwPlatformId = VER_PLATFORM_WIN32_NT then
    GetShutdownPrivileges;
    // die brauchen wir nur, wenn's mindestens Windows NT ist
  if Force then
  begin
    if (vi.dwPlatformId = VER_PLATFORM_WIN32_NT) and
       (vi.dwMajorVersion >=5) then
      flag := EWX_FORCEIFHUNG
      // geht ab Windows 2000
    else // also entweder NT oder gar windows 95/98/ME
      flag := EWX_FORCE;
  end;
  if E = EW_herunterfahren then
    ExitWindowsEx(EWX_ShutDown or flag, 0);
  if E = EW_Ruhezustand then
    SetSystemPowerState(false, Force);
  if E = EW_Standby then
    SetSystemPowerState(true, Force);
  if E = EW_Abmelden then
    ExitWindowsEx(EWX_LOGOFF or flag, 0);
  if E = EW_Neustart then
    ExitWindowsEx(EWX_REBOOT or flag,0);
end;
Tja, also ist die benutzung von
EWX_POWEROFF und
SetSystemPowerState
ähnlich, gleich, oder wie? hä? ;-)

Viele Grüße
Marco

ringli 27. Jan 2008 12:39

Re: windows herunterfahren zusammengefaßt
 
Vielleicht solltest du die ganzen IF-Abfragen durch eine CASE-Anweisung ersetzen. Dürfte übersichtlicher sein. Anbei mal die Funktion wie ich sie mir angepasst habe:
Delphi-Quellcode:
const
  EWX_STANDBY      = $20; // eigene Konstante für Standbymodus
  EWX_LOCKWKS      = $40; // eigene Konstante für das Sperren der Arbeitsstation

// Funktion um Windows herunterzufahren
// Die zu übergebenen Werte können "EWX_LOGOFF", "EWX_REBOOT",
// "EWX_SHUTDOWN", "EWX_STANDBY" oder "EWX_LOCKWKS" lauten.
function ExitWin(Flag : 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 // Windows NT/2K/XP
    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);
      case flag of
        // Abmelden, Neu starten, Herunterfahren
        EWX_LOGOFF,
        EWX_REBOOT,
        EWX_SHUTDOWN : Result := ExitWindowsEx(flag,0);
        // Standbymodus
        EWX_STANDBY : Result := SetSystemPowerState(True, True);
        // Arbeitsstation sperren
        EWX_LOCKWKS : Result := LockWorkstation;
      else
        // Wenn kein Parameter übergeben wurde ist Rückgabewert = FALSE
        Result := False;
      end;
    end
  else // Windows 9x/ME
    begin
      Result := ExitWindowsEx(flag,0);
    end;
end;

Marco Steinebach 3. Feb 2008 16:29

Re: windows herunterfahren zusammengefaßt
 
Hallo,
@Ringli: joa, hast recht, und das result wurde auch nirgends zugewiesen. Die Funktion für die Sperrung gibt's bei mir unter Delphi5 nicht, deshalbhab ich sie, erstmal, weggelassen.
Hier also das Ergebnis:
Code:
function MyExitWindows (E: TExit; force: boolean): boolean;
var
  vi: TOSVersionInfo;
  flag: integer;
begin
  if e = EW_Garnicht then
  begin
    result := true;
    exit;
  end;
  flag := 0;
  vi.dwOSVersionInfoSize:=SizeOf(vi);
  GetVersionEx (vi);
  if vi.dwPlatformId = VER_PLATFORM_WIN32_NT then
    GetShutdownPrivileges;
    // die brauchen wir nur, wenn's mindestens Windows NT ist
  if Force then
  begin
    if (vi.dwPlatformId = VER_PLATFORM_WIN32_NT) and
       (vi.dwMajorVersion >=5) then
      flag := EWX_FORCEIFHUNG
      // geht ab Windows 2000
    else // also entweder NT oder gar windows 95/98/ME
      flag := EWX_FORCE;
  end;
  case e of
    EW_herunterfahren: result := ExitWindowsEx (EWX_ShutDown or flag, 0);
    EW_Ruhezustand: result := SetSystemPowerState (false, Force);
    EW_Standby: result := SetSystemPowerState (true, Force);
    EW_Abmelden: result := ExitWindowsEx (EWX_LOGOFF or flag, 0);
    EW_Neustart: result := ExitWindowsEx (EWX_REBOOT or flag,0);
  else
    result := false;
  end;
end;
Viele Grüße
Marco

toms 3. Feb 2008 16:36

Re: windows herunterfahren zusammengefaßt
 
Zitat:

Zitat von Marco Steinebach
Hallo,
@Ringli: joa, hast recht, und das result wurde auch nirgends zugewiesen. Die Funktion für die Sperrung gibt's bei mir unter
Marco


Unter D5 kannst du die Funktion 'LockWorkStation' dynamisch laden

Delphi-Quellcode:
function LockWS: Boolean;
type
  TLockWorkStation = function: Boolean;
var
  hUser32: HMODULE;
  LockWorkStation: TLockWorkStation;
begin
  // Here we import the function from USER32.DLL
  hUser32 := GetModuleHandle('USER32.DLL');
  if hUser32 <> 0 then
  begin
    @LockWorkStation := GetProcAddress(hUser32, 'LockWorkStation');
    if @LockWorkStation <> nil then
    begin
      LockWorkStation;
      Result := True;
    end;
  end;
end;

Marco Steinebach 3. Feb 2008 16:58

Re: windows herunterfahren zusammengefaßt
 
Zitat:

Zitat von toms
Unter D5 kannst du die Funktion 'LockWorkStation' dynamisch laden...

prima! Vielen herzlichen dank! Ist eingebaut, und tut!
Viele Grüße
Marco

toms 14. Feb 2008 23:20

Re: windows herunterfahren zusammengefaßt
 
Anmerkung zu SetSystemPowerState (siehe msdn)

Zitat:

Requires Windows Vista, Windows XP, or Windows 2000 Professional.
Zitat:

Applications written for Windows Vista and later should use SetSuspendState instead


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz