# Windows Shutdown abfangen



## bobthebuilder (25. Aug 2011)

Mein Java Programm läuft im Hintergrund und soll mitbekommen, wenn der User sich vom System abmeldet bzw. es herunterfährt, um noch noch einige Sachen zu erledigen (Loggen, Verbindung schließen, etc.). Es würde mir schon reichen, wenn das unter Windows funktioniert.

Dazu habe ich schon einige Webforen durchforstet, habe die sogenannten *Shutdown Hooks* ausprobiert oder auch versucht, Systemsignale (SIGINT, etc) abzufangen mit dem *SignalHandler*.

Leider hat nichts davon wirklich funktioniert, in der Konsole oft ja, wenn man per Hand die VM mit STRG+C abgebrochen hat, aber beim User Abmelden wurde das Programm immer einfach nur weggekillt (zumindest machte es diesen Anschein).

Hat sowas von euch schon jemand gemacht? Gibt es da auch eine funktionierende Möglichkeit?


----------



## Guybrush Threepwood (25. Aug 2011)

Wenn das System sauber herunterfährt, dann sollte der Shutdown-Hook prinzipiell funktionieren. Das Programm darf aber nicht viel Zeit zum Aufräumen und Schließen benötigen. Wenn es nicht sauber herunterfährt und die JVM abgeschossen wird, dann kann Dir nichts helfen (z. B. Stromausfall etc.). Siehe: java - Handling Shutdown Event - Stack Overflow


----------



## bobthebuilder (25. Aug 2011)

Das System wurde immer völlig normal und "sauber" heruntergefahren. Das Ergebnis war immer das gleiche, das Java-Programm scheint dabei aber eines der ersten Progs zu sein, die direkt abgeschossen werden. Ich habe gerade nochmal den Code aus deinem Link probiert (obwohl sich dieser sehr an meinen ähnelt vom Prinzip her), aber es ist immer das gleiche, der Shutdown Hook Thread wird immer aufgerufen, wenn man mit STRG+C beendet oder das Programm selbst zu Ende ist (System.exit), aber beim Herunterfahren wird alles direkt abgebrochen ohne Shutdown Hook...


----------



## Andi_CH (26. Aug 2011)

Zum Thema "nicht zu viel Zeit verbrauchen" - es gibt doch Prozesse die den shutdown blockieren (es mag ein Fehlerfall sein - egal) Ist es nicht möglich Windows darum zu "bitten" ein wenig zu warten?


----------



## Cola_Colin (26. Aug 2011)

WM_QUERYENDSESSION Message (Windows)

Mit JNA hats wohl auch schonmal jemand geschaft einen Listener für WindowProc zu schreiben:
JAVA JNA WindowProc implementation - Stack Overflow


----------



## Bradworst12 (26. Aug 2011)

Also unter Windows, kannst du in den Registry Einträgen irgendwo das Zeitintervall (in ms) angeben, die Windows auf andere Prozesse warten soll bis es runterfährt. Eventuell ist das ein Ansatz für dich, aber wäre wie gesagt halt nur eine lokale Lösung, wenn nur du die Anwendung benutzt.

Grüße
Gast


----------



## Stefan Hillmann (26. Aug 2011)

Egal ob Windows, Linux etc.
Beim Herunterfahren wird kein Shutdown Hook ausgeführt.
Es obliegt dem Benutzer vor dem Herunterfahren alle Anwendungen - also JRE/JDK - sauber zu Beenden.
Fals nicht, Pech. Es wäre auch dumm, beim herunterfahren einen neuen Thread start zu lassen, was der Shutdown-Hook ja tut.
Allerdings wäre es vieleicht möglich, das Term Signal mit den Klassen SignalHandler und Signal abzufangen und zu reagieren.
(sum.misc.SignalHandler und sun.misc.Signal). Das wäre mein Ansatz für diese Aufgabenstellung.


----------



## bobthebuilder (27. Aug 2011)

Also, den SignalHandler hatte ich ja, wie oben geschrieben, auch schon probiert, wenn der überhaupt reagierte, dann auch nur auf STRG+C.



> Falls nicht, Pech. Es wäre auch dumm, beim herunterfahren einen neuen Thread start zu lassen, was der Shutdown-Hook ja tut.



Nunja, so kategorisch klar ist das ja nun nicht, dann könnte man auch gleich sagen, es wäre dumm bei Programm beenden einen Thread zu starten, aber genau dazu ist nunmal der ShutdownHook da.

Interessanterweise wird in vielen Dokus beschrieben, dass der ShutdownHook auch für den OS Shutdown da sei...als ob es mal "früher" funktioniert hat in älteren JREs o.ä.

In der WindowsRegistry möchte ich auch nicht rumspielen, das ist für mich keine Lösung, ich denke auch das bringt nix, denn "lang" dauert mein Shutdown Hook nicht, er wird ja nie aufgerufen...

Das mit der JNI Bibliothek scheint mir noch am sinnvollsten...nur am Ende wird es so wie beim SignalHandler, was nutzt eine C-Bibliothek, wenn die ganze JVM trotzdem von Windows abgeschossen wird...


----------



## Empire Phoenix (28. Aug 2011)

Wie wärs andersrum? nen mini c programm das dein java program als subprocess startet, das c programm blockiert das runterfahren und gibt einfach an den java subprocess per instream nen shutdown befehl weiter?

AM rande was genau muss das programm überhaupt tun? Weil jede gut programmierte DB kommt damit zurecht wennse abgeschossen wird. Und wennde den log entsprechend immer flushst hasste da auch alles rausgeschreiben.


----------



## bobthebuilder (31. Aug 2011)

Empire Phoenix hat gesagt.:


> Wie wärs andersrum? nen mini c programm das dein java program als subprocess startet, das c programm blockiert das runterfahren und gibt einfach an den java subprocess per instream nen shutdown befehl weiter?




Könnte da jemand einen kleinen Codeschnipsel zusammenbasteln? Mit C(++) bin ich nach wie vor Neuling und habe mich gestern schon intensiv mit dem Shutdown abfangen in C beschäftigt, bekomme es aber vorerst noch nicht so richtig hin. :rtfm:



Empire Phoenix hat gesagt.:


> AM rande was genau muss das programm überhaupt tun? Weil jede gut programmierte DB kommt damit zurecht wennse abgeschossen wird. Und wennde den log entsprechend immer flushst hasste da auch alles rausgeschreiben.



Das Java Programm ist nunmal so "da" wie es ist, beim Beenden sollen nicht nur Verbindungen geschlossen werden, es soll, einfach gesagt, protokolliert werden, zu welcher Zeit beendet wurde und deswegen kann es nicht einfach "abgeschossen" werden.


----------



## faetzminator (31. Aug 2011)

Unter Linux werden Prozesse normalerweise mit [c]kill -15[/c] (SIGTERM) beendet, danach - wenn immer noch am laufen - mit [c]kill -9[/c] (SIGKILL) abgeschossen. Nichtsdestotrotz hab ich dort auch schon festgestellt, dass schon nur beim SIGTERM zu wenig Zeit vorhanden war, alles abzuarbeiten. Sind villeicht einfach nur ein paar Prozessortakte?
Auf alle Fälle solltest du nicht mit den Shutdownhooks arbeiten, da die nicht zuverlässig sind. Wenn du z.B. Settings speichern willst, kannst du dir bei Änderungen irgendein Tempfile machen (anstatt gleich das richtige Configfile zu überschreiben). Und wenn das Programm startet und das File noch dort ist - dann kann der User die Einstellungen wiederherstellen. Natürlich wird bei einem Save oder beim Beenden (mit oder ohne Save) das File gelöscht.


bobthebuilder hat gesagt.:


> Das Java Programm ist nunmal so "da" wie es ist, beim Beenden sollen nicht nur Verbindungen geschlossen werden, es soll, einfach gesagt, protokolliert werden, zu welcher Zeit beendet wurde und deswegen kann es nicht einfach "abgeschossen" werden.


Da kannst du aber auch einfach jede Minute irgendwo hinloggen o.ä. Warum ist das für dich so wichtig? Oder allenfalls sieht man auch den Timestamp des Logs!?


----------

