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 (0x1) 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 0x1
#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:

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 Gedanken zu „Vista beendet Programme auch wenn WM_QUERYENDSESSION FALSE returniert“

    1. 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.

  1. Pingback: JIRA: PM OLAP
  2. 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 (?)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.