![]() |
WinShutdown per Aufgabenplanung
Schönen guten Morgen,
ich hoffe, dass ihr mir evtl. weiterhelfen könnt. Derzeit nutze ich folgendes Programm um Windows herunterzufahren und dabei die Updates zu installieren:
Delphi-Quellcode:
Das funktioniert so lange bis ich die Aufgabe als Task "unabhängig von der Benutzeranmeldung" ausführen lasse. Hierbei ist es egal, ob ich SYSTEM nehme oder einen personalisierten Benutzer.
function WindowsShutDown(Computer: PChar; Msg: PChar; Time: Word; Force: Boolean; Reboot: Boolean): Boolean;
var rl: Cardinal; hToken: Cardinal; tkp: TOKEN_PRIVILEGES; flags: DWORD; begin Result:=False; if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then RaiseLastOSError else begin if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then begin tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; tkp.PrivilegeCount := 1; AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl); if GetLastError <> ERROR_SUCCESS then RaiseLastOSError else begin if Win32MajorVersion >= 6 then begin //Flags if Reboot then flags := SHUTDOWN_FORCE_SELF or SHUTDOWN_GRACE_OVERRIDE or SHUTDOWN_RESTART else flags := SHUTDOWN_FORCE_SELF or SHUTDOWN_GRACE_OVERRIDE or SHUTDOWN_INSTALL_UPDATES; //Befehl ausführen if InitiateShutdown(Computer, Msg, Time, flags, 0) = ERROR_SUCCESS then result := True else RaiseLastOSError; end else begin if InitiateSystemShutdown(Computer, Msg, Time, Force, Reboot) then result := True else RaiseLastOSError; end;{else} end;{else} end else RaiseLastOSError; end;{else} end; Ich sehe den Zusammenhang mit der Privilege-Abfrage. Es stellt sich die Frage, ob es dafür der richtige Ansatz ist und ob ich diese Abfrage überhaupt benötige. Evtl. wäre auch der Einsatz von ImpersonateLoggedOnUser möglich? Ich hoffe, dass ihr mir hier ein wenig unter die Arme greifen könnt. Ziel ist es einen Pool von virtuellen Maschinen per Aufgabenplanung zeitgesteuert das Programm ausführen zu lassen. Danke und Gruß boese² |
AW: WinShutdown per Aufgabenplanung
Deine Routine gibt beim Ausführen entweder ein
Delphi-Quellcode:
zurück, oder es wird eine Exception geworfen.
True
Wenn es aber nur einen möglichen Wert gibt, warum gebe ich den Wert dann zurück? Eine Exception unterbricht ausserdem die weitere Code-Ausführung. Mit diesen beiden Erkenntnissen lässt sich dein Code erheblich verschlanken:
Delphi-Quellcode:
procedure Win32CheckSuccess(AResult : DWORD);
begin if AResult <> ERROR_SUCCESS then RaiseLastOSError; end; procedure WindowsShutDown( Computer: PChar; Msg: PChar; Time: Word; Force: Boolean; Reboot: Boolean ); var rl : Cardinal; hToken: Cardinal; tkp : TOKEN_PRIVILEGES; flags : DWORD; begin Win32Check( OpenProcessToken( GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken ) ); Win32Check( LookupPrivilegeValue( nil, 'SeShutdownPrivilege', tkp.Privileges[ 0 ].Luid ) ); tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED; tkp.PrivilegeCount := 1; Win32Check( AdjustTokenPrivileges( hToken, False, tkp, 0, nil, rl ) ); if Win32MajorVersion >= 6 then begin // Flags if Reboot then flags := SHUTDOWN_FORCE_SELF or SHUTDOWN_GRACE_OVERRIDE or SHUTDOWN_RESTART else flags := SHUTDOWN_FORCE_SELF or SHUTDOWN_GRACE_OVERRIDE or SHUTDOWN_INSTALL_UPDATES; // Befehl ausführen Win32CheckSuccess( InitiateShutdown( Computer, Msg, Time, flags, 0 ) ); end else Win32Check( InitiateSystemShutdown( Computer, Msg, Time, Force, Reboot ) ); end; |
AW: WinShutdown per Aufgabenplanung
Hi Rufo,
danke für die Optimierung, löst aber nicht das Problem, oder? //edit: Getestet. Verhalten bleibt leider wie gehabt. Gruß boese² |
AW: WinShutdown per Aufgabenplanung
Hat es einen Grund warum es ein eigenes Programm sein soll?
Ich hätte mir jetzt eine Batch erstellt und dort "shutdown -s -t 0" aufgerufen. Oder auch direkt, müsste man mal ausprobieren. Die Installation der Updates sollte auch klappen. |
AW: WinShutdown per Aufgabenplanung
Shutdown war natürlich mein erster Versuch. Dabei werden keine Updates installiert. Auch das vorherige installieren per Batch wäre eine Variante, aber ich möchte den Benutzer erst abgemeldet und alle Anwendungen geschlossen haben.
Der Aufruf mit Updates ist nur per API Call realisierbar. Dieser wird auch von m$ auf dem Herunterfahren-Button angewendet! |
AW: WinShutdown per Aufgabenplanung
Moin,
hast Du auch mal im Eventlog nachgesehen, was passiert ist? Vielleicht habe ich es übersehen, aber: Unter welchem Betriebssystem soll das funktionieren? |
AW: WinShutdown per Aufgabenplanung
Versuche es mal mit
Delphi-Quellcode:
SeRemoteShutdownPrivilege
|
AW: WinShutdown per Aufgabenplanung
@Christian:
Für die Aufgabenplanung ist die Aufgabe sauber durchgeführt worden: Zitat:
@Günther: Danke, werde ich mal weitergeben und ausprobieren. Gruß boese² |
AW: WinShutdown per Aufgabenplanung
Nachtrag zu Günther:
Funktioniert (leider) auch nicht. Ich verstehe nicht, warum eine entsprechende Option in der regulären shutdown.exe fehlt. Diese lässt sich problemlos über "Unabhängig von der Benutzeranmeldung" ausführen. Ich habe übrigens noch zusätzlich die lokale Sicherheitsrichtlinie dahingehend geprüft, dass ein Herunterfahren auch ohne Anmeldung möglich ist. Daran kann es also auch nicht liegen. Er scheint zwingend eine aktive Session zu benötigen... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz