![]() |
Windows beenden und dabei Updates installieren
Hallo DPler,
ich habe in meinem Programm (Kiosk-Anwendung) den Punkt Beenden, hierbei soll der Rechner heruntergefahren werden. Bisher habe ich das mit ShellExecute() und "shutdown -s -f -t 0" realisiert. Dabei ist mir jedoch aufgefallen das keine Updates installiert werden falls welche heruntergeladen wurden. Die Windows Update Einstellungen stehen auf "Updates herunterladen, aber Installation manuell durchführen". Es sollen nämlich die Updates erst beim Beenden installiert werden. Jetzt habe ich im internet und auch hier im Forum gesucht und bin auf einen ![]() ![]() Also dachte ich mir nehme ich doch den Code und alles wäre geritzt aber nix da der Rechner fährt direkt runter. :?
Delphi-Quellcode:
Jetzt ging es in dem Thread weiter und Jemand schlug die Funktion
function WindowsShutDown(Computer : string; Msg : string; Time: Word; Force : Boolean; Reboot: Boolean) : Boolean;
var rl, hToken : Cardinal; tkp : TOKEN_PRIVILEGES; begin Result:=False; if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then ShowMessage('Fehler beim Windows-Shutdown aufgetreten.') 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 ShowMessage('Fehler beim Windows-Shutdown aufgetreten.') else begin Result:=InitiateSystemShutdown(PChar(Computer), PChar(Msg), Time, Force, Reboot); if Result = False then ShowMessage('Fehler beim Windows-Shutdown aufgetreten.'); end; end else ShowMessage('Fehler beim Windows-Shutdown aufgetreten.'); end; end;
Delphi-Quellcode:
vor mit dem Flag SHUTDOWN_INSTALL_UPDATES.
InitiateShutdown()
Mir gelingt es jedoch einfach nicht diese Funktion zu implementieren.
Delphi-Quellcode:
Die Entwicklung geschieht in Delphi 2009 unter Windows XP, die Software wird jedoch nur auf Windows 7 Rechner eingesetzt.
const
SHUTDOWN_FORCE_OTHERS = $00000001; SHUTDOWN_FORCE_SELF = $00000002; SHUTDOWN_GRACE_OVERRIDE = $00000020; SHUTDOWN_HYBRID = $00000200; SHUTDOWN_INSTALL_UPDATES = $00000040; SHUTDOWN_NOREBOOT = $00000010; SHUTDOWN_POWEROFF = $00000008; SHUTDOWN_RESTART = $00000004; SHUTDOWN_RESTARTAPPS = $00000080; type function InitiateShutdown(lpMachineName, lpMessage: LPWSTR; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; implementation function InitiateShutdown; external advapi32 name 'InitiateShutdown'; Hat jemand eine Idee was ich falsch mache bzw. eine Idee woran es liegen kann das man beim herunterfahren die Updates nicht installiert werden? |
AW: Windows beenden und dabei Updates installieren
Zitat:
|
AW: Windows beenden und dabei Updates installieren
Ich habe den Fehler selbst schon gefunden, die function 'InitiateShutdown' existiert nicht in der Advapi32.dll sondern nur die beiden Ansi und Unicode varianten 'InitiateShutdownA' und 'InitiateShutdownW'.
Mit folgender Implementierung hat es geklappt, und scheinbar werden jetzt auch die Updates beim Beenden installiert.
Delphi-Quellcode:
Mal schauen welche Überraschung Windows noch bereit behält :tongue:
const
SHUTDOWN_FORCE_OTHERS = $00000001; SHUTDOWN_FORCE_SELF = $00000002; SHUTDOWN_GRACE_OVERRIDE = $00000020; SHUTDOWN_HYBRID = $00000200; SHUTDOWN_INSTALL_UPDATES = $00000040; SHUTDOWN_NOREBOOT = $00000010; SHUTDOWN_POWEROFF = $00000008; SHUTDOWN_RESTART = $00000004; SHUTDOWN_RESTARTAPPS = $00000080; type TInitiateShutdown = function( {$IFDEF UNICODE} lpMachineName, lpMessage: PWideChar; {$ELSE} lpMachineName, lpMessage: PAnsiChar; {$ENDIF} dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; function InitiateShutdownA(lpMachineName, lpMessage: PAnsiChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; function InitiateShutdownW(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; var InitiateShutdown: TInitiateShutdown = {$IFDEF UNICODE} InitiateShutdownW; {$ELSE} InitiateShutdownA; {$ENDIF} implementation function InitiateShutdownA; external advapi32 name 'InitiateShutdownA'; function InitiateShutdownW; external advapi32 name 'InitiateShutdownW'; |
AW: Windows beenden und dabei Updates installieren
Zitat:
cu |
AW: Windows beenden und dabei Updates installieren
Zitat:
|
AW: Windows beenden und dabei Updates installieren
@TUX_der_Pinguin
Schau doch mal in deinem Delphi in der Windows Unit nach, wie Emba diese Umleitung der API-Calls macht (Ansi/Unicode). Das ist dort wesentlich eleganter gelöst ;) |
AW: Windows beenden und dabei Updates installieren
Zitat:
Delphi-Quellcode:
function InitiateShutdown(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall;
{$EXTERNALSYM InitiateShutdown} function InitiateShutdownA(lpMachineName, lpMessage: PAnsiChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownA} function InitiateShutdownW(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownW} implementation function InitiateShutdown; external advapi32 name 'InitiateShutdownW'; function InitiateShutdownA; external advapi32 name 'InitiateShutdownA'; function InitiateShutdownW; external advapi32 name 'InitiateShutdownW'; |
AW: Windows beenden und dabei Updates installieren
Ich würde es noch so abändern:
Delphi-Quellcode:
Und jetzt hat man eine automatische Umleitung bei der Verwendung von
function InitiateShutdown(lpMachineName, lpMessage: PChar {PWideChar}; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall;
{$EXTERNALSYM InitiateShutdown} function InitiateShutdownA(lpMachineName, lpMessage: PAnsiChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownA} function InitiateShutdownW(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownW} implementation function InitiateShutdown; external advapi32 name {$IFDEF UNICODE}'InitiateShutdownW'{$ELSE}'InitiateShutdownA'{$ENDIF}; function InitiateShutdownA; external advapi32 name 'InitiateShutdownA'; function InitiateShutdownW; external advapi32 name 'InitiateShutdownW';
Delphi-Quellcode:
InitiateShutdown();
|
AW: Windows beenden und dabei Updates installieren
Ich habe bis heute nie verstanden was das für einen Sinn macht die Deklarationen in zwei Teile (Interface und implementation) aufzusplitten. Warum macht man das?
|
AW: Windows beenden und dabei Updates installieren
Weil man es kann :mrgreen:
Hat wohl eher etwas mit der Übersichtlichkeit zu tun wenn das
Delphi-Quellcode:
nicht auch noch in der Zeile steht.
; external advapi32 name 'InitiateShutdownA';
Ansonsten ist es wurscht ... |
AW: Windows beenden und dabei Updates installieren
Hallo,
wäre evtl. jemand so freundlich das geschilderte Programm in der kompletten endgültigen Fassung zu quoten, so dass man es seinem Compiler vor die Füße werfen kann? Danke und Gruß boese² |
AW: Windows beenden und dabei Updates installieren
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Im Anhang befindet sich die Projekt Dateien samt Quelltext und EXE-File.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm15 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form15: TForm15; implementation uses Unit2; {$R *.dfm} procedure TForm15.Button1Click(Sender: TObject); begin WindowsShutDown(nil, nil, 0, True, False); end; end.
Delphi-Quellcode:
unit Unit2;
interface uses Windows, SysUtils; const SHUTDOWN_FORCE_OTHERS = $00000001; SHUTDOWN_FORCE_SELF = $00000002; SHUTDOWN_GRACE_OVERRIDE = $00000020; SHUTDOWN_HYBRID = $00000200; SHUTDOWN_INSTALL_UPDATES = $00000040; SHUTDOWN_NOREBOOT = $00000010; SHUTDOWN_POWEROFF = $00000008; SHUTDOWN_RESTART = $00000004; SHUTDOWN_RESTARTAPPS = $00000080; function WindowsShutDown(Computer: PChar; Msg: PChar; Time: Word; Force: Boolean; Reboot: Boolean): Boolean; function InitiateShutdown(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdown} function InitiateShutdownA(lpMachineName, lpMessage: PAnsiChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownA} function InitiateShutdownW(lpMachineName, lpMessage: PWideChar; dwGracePeriode, dwShutdownFlags, dwReason: DWORD): DWORD; stdcall; {$EXTERNALSYM InitiateShutdownW} implementation function InitiateShutdown; external advapi32 name {$IFDEF UNICODE}'InitiateShutdownW'{$ELSE}'InitiateShutdownA'{$ENDIF}; function InitiateShutdownA; external advapi32 name 'InitiateShutdownA'; function InitiateShutdownW; external advapi32 name 'InitiateShutdownW'; 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; end. |
AW: Windows beenden und dabei Updates installieren
Hey,
vielen Dank für die Antwort. Das Programm hat tatsächlich die Windows Mimik angeschmissen und beim Herunterfahren Updates installiert. Damit ich das Programm aber nun in meiner Aufgabenplanung nutzen kann bräuchte ich eine direkte Ausführung des Befehls bei Aufruf der *.exe ohne Umweg über die GUI bzw. einen entsprechenden Schalter. Wärst du nochmal so freundlich? Gruß boese² |
AW: Windows beenden und dabei Updates installieren
Liste der Anhänge anzeigen (Anzahl: 1)
Das Forum soll ja eigentlich nur als eine Art Hilfestellung dienen und nicht das andere einem die Arbeit abnehmen.
Aus dem Beispiel Programm eine Konsolen Anwendung zu erstellen die beim Aufruf direkt den Befehl ausführt ist nur eine Sache von ein paar Minuten. Aber ich will heute mal nicht so sein und habe so eine kleine Konsolen Anwendung erstellt, die sich mit den entsprechenden Parametern aufrufen lässt. Über Folgenden Befehl fährt der Rechner herunter und sollte dabei die Updates installieren... Zitat:
|
AW: Windows beenden und dabei Updates installieren
Hi,
vielen Dank für die Bereitstellung. Leider habe ich weder die Umgebung dafür den Code zu kompilieren noch das Know-How Anpassungen daran vorzunehmen. Ich hatte halt nur das Glück beim Forschen nach einer Lösung über "InitiateShutdown" gestolpert zu sein und dann noch mehr Glück, dass hier jemand mit Programmier-Erfahrung in dem Bereich das gleiche Vorhaben hatte. Nochmals vielen Dank für die Bereitstellung dieser Lösung. Gruß boese² |
AW: Windows beenden und dabei Updates installieren
Liste der Anhänge anzeigen (Anzahl: 1)
So Version 1.0.1 mit optimiertem Code.
|
AW: Windows beenden und dabei Updates installieren
Liste der Anhänge anzeigen (Anzahl: 1)
Version 1.0.2 mit 'SeRemoteShutdownPrivilege' anstatt von 'SeShutdownPrivilege'
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:24 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