![]() |
Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Es geht um das Herunterfahren bzw. Abmelden des Benutzers. Ich stelle hier grade fest dass beim Herunterfahren Code im
Delphi-Quellcode:
-Abschnitt einer Unit nicht ausgeführt wird. Wenn ich das Herunterfahren "fälsche" indem ich mir selbst einfach eine
finalization
Delphi-Quellcode:
-Nachricht schicke beendet sich die VCL-Anwendung zwar auch, führt aber auch ordentlich alles im finalization-Abschnitt aus.
WM_ENDSESSION
Mein kompletter Code sieht folgendermaßen aus:
Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
begin Application.HookMainWindow(wndProcHook); end; function TForm3.wndProcHook(var message: TMessage): Boolean; begin Result := false; case message.Msg of WM_ENDSESSION: begin placefile('ZZzzz 1'); sleep(5000); placefile('ZZzzz 2'); Halt(0); end; end; end; initialization finalization placeFile('unit finalization'); end.
Delphi-Quellcode:
legt nur eine leere Datei im gleichen Verzeichnis wie die exe an.
placeFile(..)
Wenn ich das Herunterfahren "fälsche" erhalte ich die drei Dateien "ZZzzz 1", "ZZzzz 2" und "unit finalization". Melde ich mich richtig ab, fehlt das "unit finalization" einfach. Ich habe keine Ahnung wie ich das debuggen könnte. Meine Vermutung: Irgendeine Unit-Finalisierung der VCL ist vor meiner dran. Dort drin werden wohl weiter kurz Messages abgearbeitet. Das ist tödlich, denn Windows nimmt so etas nach einem
Delphi-Quellcode:
zum Anlass das Programm direkt abzuschießen.
WM_ENDSESSION
Siehe hier: ![]() Es ist eine schwache Vermutung, aber die einzige die ich habe. Mein Ziel ist es, dass die Finalisierung aller Units ausgeführt wird und Windows meine Anwendung nicht vorher abschießt. Kann mir jemand helfen? :pale: |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Ich meine, die 5 Sekunden sind genau die Zeit, die Windows wartet, bis es eine Anwendung als unresponsive einfach killt.
Slightly OT: Den Hook kannst du dir sparen. Dies tut's auch:
Delphi-Quellcode:
procedure wmEndSession(var Message: TMessage); message WM_ENDSESSION;
|
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Wenn du noch etwas zu erledigen hast, dann musst du das währen der
Delphi-Quellcode:
Nachricht machen.
WM_ENDSESSION
Nach dieser Nachricht kann alles passieren (z.B. Windows killt den Prozess). |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Und wenn du etwas erledigen musst, das länger dauert, musst du Windows das mitteilen. Du kannst dich entsprechend registrieren und wirst dann auch auf dem Herunterfahren-Bildschirm angezeigt in der Liste der Anwendungen, die das Herunterfahren blockieren.
Wir haben keinerlei wichtigen Code in finalization drin. Es gibt Startup- und Shutdown-Abläufe, die aber sämtlich innerhalb des begin..end des Projekts ablaufen. In finalization passieren nur noch Sachen, auf die wir keinen Einfluss haben (Delphi-Units, 3rd-Party Units, ...). Das macht auch das Debuggen deutlich einfacher. |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Wobei, ab Vista ist Windows da nicht mehr so gutmütig. Und das ist auch richtig.
Sorg dafür, dass da nichts wichtiges mehr passiert. |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Vielen Dank für die Antworten bislang.
Zitat:
Zitat:
![]() Vielleicht könnte es doch helfen, denn vielleicht gelten die von Uwe angesprochenen fünf Sekunden ja nachträglich wenn die Anwendung plötzlich kein sichtbares Fenster mehr hat: Zitat:
Zitat:
Wir haben leider durchaus Anwendungen welche im Klassen-Destruktor noch beispielsweise Dateien flushen und schließen. Jetzt im Nachhinein zu sehen dass höchstwahrscheinlich nicht ausgeführt wird wenn Windows heruntergefahren wird und die Anwendung noch offen ist schockiert mich ehrlich gesagt etwas ziemlich. Zitat:
Meine Vermutung zur Ursache des vorzeitigen Ablebens bleibt weiterhin dass irgendeine Unit-Finalisierung der VCL/RTL weiterhin in der Nachrichtenschleife der Anwendung wühlt und Windows die Anwendung darauf hin direkt killt. |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Zitat:
Delphi-Quellcode:
geschickt hast.
WM_ENDSESSION
Wie schickst du denn? Mit
Delphi-Quellcode:
?
SendMessage
Dann bleibt also diese sendende Anwendung hängen? (Weil
Delphi-Quellcode:
blockiert, bis es eine Rückmeldung bekommt)
SendMessage
Oder bekommst du dort doch eine Rückmeldung? Einfach mal ausprobieren und ich wette, da kommt etwas zurück :) |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Nur mal so al "Spekulatius":
Warum Halt? Würde das Programm lieber "regulär" beenden, statt
Delphi-Quellcode:
mit
Halt(0);
Delphi-Quellcode:
.
Application.MainForm.Close;
Beende meine Programme eigentlich immer damit, dass ich das Hauptformular schließe. Die Hilfe von Delphi 7 sagt zu Halt: Zitat:
Ansonsten: Wie wäre es mit dem ebenfalls in der Hilfe beschriebenen: Zitat:
Delphi-Quellcode:
?
Application.Terminate;
Warum das Programm "brutal" mit Halt beenden, wenn es auch moderat geht? |
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Zitat:
1. Die VCL auch von selbst so macht (siehe weiter unten) 2. Ich keine andere Möglichkeit kenne die Units finalisieren zu lassen Zitat:
Delphi-Quellcode:
Vcl.Forms.TApplication.WndProc(..)
begin [...] WM_ENDSESSION: begin [...] if EndSessionMsg.EndSession then begin Application.Terminate; Halt; end; [...] end;
Delphi-Quellcode:
ist, soweit ich weiß, die einzige Möglichkeit, die Unit-Finalisierung aufzurufen.
Halt
System.Halt sagt:
Delphi-Quellcode:
Eine VCL-Anwendung antwortet somit nie auf ein
procedure _Halt0;
begin [...] FinalizeUnits; [...] WinApi.Windows.ExitProcess(ExitCode); end;
Delphi-Quellcode:
, sondern schießt sich vorher ab. Klingt komisch, ist aber doch völlig legitim. Ich denke eher das Abräumen der Formulare sorgt dafür dass Windows denkt "So, der ist ja durch. Weg mit dem".
WM_ENDSESSION
Ich versuche mal, schon alle Formulare in
Delphi-Quellcode:
zu zerstören. Vielleicht bringt das ja was...
WM_QUERYENDSESSION
|
AW: Windows tötet Delphi-Anwendung noch vor Unit-Finalisierung
Zitat:
Delphi-Quellcode:
programmiert hat? :stupid:
procedure TApplication.WndProc(var Message: TMessage);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:25 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 by Thomas Breitkreuz