Vista beendet Programme auch wenn WM_QUERYENDSESSION FALSE returniert
Jeder kennt die nette Nachricht WM_QUERYENDSESSION die einem mitteilt, dass das System herunter gefahren wird, oder der Benutzer sich abmeldet.
Und wir alle sind auch einfach gewöhnt FALSE zu returnieren wenn wir das nicht wollen und damit waren wir sicher das WM_ENDSESSION mit FALSE gesendet wird und das System nicht herunterfährt. Ja! Richtig gelesen waren!
Das hat sich mit Vista nun auch geändert. Wird im lParam Bit ENDSESSION_CLOSEAPP (0×1) gesetzt, dann spielt es keine Rolle wie das Programm es gerne hätte. Die Applikation soll und muss beendet werden. D.h. die Applikation muss auch mit dem Zustand zurecht kommen, dass die Daten nicht gesichert sind, bzw. eben mit dem Zustand, der uns veranlasst hat FALSE zu returnieren.
Dies war bisher ausgeschlossen. Deshalb sollte man sich über das Verhalten seines Programmes an dieser Stelle mal Gedanken machen.
Für MFC Anwender noch eine kleine Herausforderung denn OnQueryEndSession wird von der MFC ohne Parameter aufgerufen und ohne das Vista SDK ist natürlich ENDSESSION_CLOSEAPP nicht definiert
#ifndef ENDSESSION_CLOSEAPP
#define ENDSESSION_CLOSEAPP 0×1
#endif
…
BOOL CMainFrame::OnQueryEndSession()
{
// Need to get the lParam value for this message to
// determine the reason of the shutdown
LPARAM lParam = AfxGetCurrentMessage()->lParam;
if (lParam & ENDSESSION_CLOSEAPP)
{
// We are forced to exit here, the user want to close the
// application, even if we loose data
OnForcedShutdown():
return TRUE;
}
else
// do the default
return __super::OnQueryEndSession();
}
BTW: Eine normale MFC Applikation berücksichtigt dies nicht korrekt. Es wird der Status von allen Dokumenten geprüft und evtl. einen entsprechender Dialog angezeigt, wenn eines der Dokumente nicht gespeichert ist. Wird aber die Anfrage mit ENDSESSION_CLOSEAPP gesendet, dann muss die Antwort in 5 Sekunden erfolgen. Einen Dialog anzuzeigen bzw. Frage zu stellen wie es die Standardimplementierung macht, passt hier nicht!
Man sollte sich unbedingt hier die Vista Änderungen zu Gemüte führen und gegebenenfalls auch ShutdownBlockReasonCreate implementieren.
Weitere Infos zu den Änderungen findet sich in der aktuellen MSDN:
- WM_QUERYENDSESSION
- Guidelines for Applications
- Shutdown Changes for Windows Vista
- ShutdownBlockReasonCreate
Anmerkung: Jeder der sich mit der Vista-Zertifizierung auseinandergesetzt hat wird erkannt haben, dass es sich bei dem hier beschriebenen Verhalten um den Test Case 30 handelt, bzw. die Requirements, Reliability 3.1!
5 Kommentare zu “Vista beendet Programme auch wenn WM_QUERYENDSESSION FALSE returniert”
Link für diesen Beitrag | RSS-Feed zu diesem Beitrag
Hinterlassen sie einen Kommentar:
Beachten sie bitte, dass Kommentare evtl. nicht sofort hier erscheinen. Die Kommentare werden zur Moderation an den Webmaster gesendet. Es kann also etwas dauern, bis Ihr Kommentar hier veröffentlicht wird!
on Di 10 Mrz 2009 um 20:33 #
hannes
das das windows programme einfachso beendet,.?
wie kann ich das ausstellen?
on Mi 11 Mrz 2009 um 09:10 #
Martin Richter
Ich weiß nicht wie ich Deine Frage verstehen soll. Du wirst benachrichtigt und Du kanst reagieren. Du hast 5 Sekunden
Es steht alles in meinem Artikel. Lies doch bitte die entsprechenden Links, die ich angegeben habe. Da steht alles wissenswerte.
on Mi 06 Apr 2011 um 12:00 # JIRA: PM OLAP
[PMOLAP-677] Cube file destroyed after save…
Microsoft changed the shutdown behaviour in Vista/Win7. It looks like, that this change influences the closing behaviour of the command window (same system message is sent in both cases). The console window [closes now within 5 seconds|http://msdn…….
on Di 08 Mai 2012 um 10:29 #
Martin
Hi Namensvetter, danke für Deine vielen Tips. Bisher bin ich eher stiller Leser, aber in letzter Zeit stolpere ich auch öfters über Dinge, die unter XP noch gut liefen und ab Vista “anders”
So gut die Gedanken, die MS sich bei den Änderungen am Powermanagement gemacht hat, auch sein mögen, an manchen Stellen hakt es dann doch. Klar, ich kann verstehen, daß ein Anwender gerne sehen möchte, daß sein Notebook gerade nicht herunterfahren mag, weil Programm XY dies verhindert. Aber manche von uns (ich) haben beispielsweise einen Server in einer dunklen Ecke der Wohnung / des Büros stehen, welcher nicht den ganzen Tag laufen muß (Strom sparen) und durch einen Client automatisch eingeschaltet wird. Das Ding muß einfach nur funktionieren, bedient wird es nicht wirklich, es stellt nur Hardware für die Clients zur Verfügung. Sobald alle Clients verschwunden sind, läuft er noch für 10 Minuten weiter (konfigurierbar) und schaltet sich dann automatisch ab, wenn nicht irgendein Client wieder sagt “hey, ich brauch Dich noch”. Leider ist meine Steuersoftware nicht die einzige, die sich hier einklinkt und ohne Gegenmaßnahmen würde dann mein Mechanismus versagen und die andere Software fährt mir den Server herunter. Deswegen war/ist es unter XP von Vorteil, daß der PBT_APMQUERYSUSPEND Event verschickt wird und man darauf reagieren kann. So kann ich mit meiner Software genau steuern, wann der PC herunter gefahren werden darf. Die andere Software darf dies übrigens auch, z.B. wenn sie eine Fernsehsendung aufzeichnen möchte – wer mag schon bruchstückhafte Aufnahmen… Und natürlich muß man dem Betriebssystem mit “SetThreadExecutionState” mitteilen, daß es noch gebraucht wird.
Unter Windows Vista oder 7 wüßte ich derzeit noch nicht, wie ich dies lösen könnte und deshalb bleibt auf dem Server erst einmal XP drauf.
Ich habe gelesen, ggf. ausschließlich mit “SetThreadExecutionState” zu arbeiten und keinen expliziten Shutdown selbst auslösen (?). D.h. ich setze in regelmäßigen Abständen ein “SetThreadExecutionState” ab. Unter XP brauchte man dies nur eventgesteuert auf Anforderung, ab Vista per Timer alle paar Sekunden (?)
on Di 08 Mai 2012 um 10:39 #
Martin Richter
Alle paar Sekunden SetThreadExecutationState ausführen genügt…