Applications that throw up dialogs and block operating system shut down can frustrate end users. Prior to Windows Vista, the shut down experience could be confusing and tedious if multiple applications blocked shut down because this would cause multiple prompts to terminate an application. To address this problem, Microsoft has redesigned the shut down dialog in Windows Vista, as shown in Figure 1.
Figure 1. Application Shut Down in Windows Vista
This dialog has a number of interesting features worth noting:
- Unlike the Windows XP dialog, which used a standard dialog box that easily could get lost in a storm of dialog boxes from various applications during system shut down, the Windows Vista dialog is a visually distinctive full-screen overlay.
- The application that is blocking the operating system (Paint, in this case) and any other applications still running (Notepad, in this case) are clearly identified.
- The user is presented with an option to Shut down now.
Of all of these features, the last one is the most interesting, particularly for applications that previously relied on being able to block shut down. An application is notified of an impending operating system shut down via a WM_QUERYENDSESSION message, which is delivered to each application sequentially. Each application has five seconds to respond to this message before the operating system takes over and informs the user that the application is not responding (this is the screen shown in Figure 1). An application also can respond to the WM_QUERYENDSESSION by returning FALSE, which will stop the operating system shut down. When an application responds with FALSE, it is up to the application to inform the user why shut down was cancelled.
With the addition of the Shut down now option in Figure 1, the new flag ENDSESSION_FORCEFULSHUTDOWN is sent with WM_QUERYENDSESSION when the user selects this option, and an application failing to respond (because it is showing a Save File dialog, for example) will be forcibly terminated. For an application running on Windows Vista, it is not safe to assume that the operating system will allow WM_QUERYENDSESSION to be blocked indefinitely while a dialog box is displayed.
Windows Vista resolves the mystery failed operating system shut down by displaying an operating system message similar to that shown in Figure 1. This message will display as soon as FALSE is returned from a WM_QUERYENDSESSION message handler. Figure 2 shows the message display to the user.
Figure 2. Blocked Shut Down in Windows Vista
The pre-Vista shut down procedure can make for fairly slow and confusing shut downs if a number of applications want to block or delay shut down. Although the new user option of forcibly ending all applications can speed up shut down, it does so at the risk of data loss for applications that are not given the chance to prompt a user for a file name or inform them of an important operation they are completing.
To compensate for the changes to the way the operating system delivers shut down notifications in Vista—particularly the potential inability to block a WM_QUERYENDSESSION message—an application can inform the operating system when it is completing an operation that cannot be recovered after a shut down. This notification is achieved via the new ShutdownBlockReasonCreate, ShutdownBlockReasonDestroy, and ShutdownBlockReasonQuery APIs. Calling ShutdownBlockReasonCreate will result in a message being shown to the user during shut down, as shown in Figure 3.
Figure 3. Shut Down in Windows Vista with Block Reason
Using the new ShutdownBlockReasonXXX APIs does not remove the need to use the WM_QUERYENDSESSION message to block or delay shut down. The key advantage of the ShutdownBlockReasonXXX APIs is that the user is always informed of why the application wants to block a shut down, even if it has not received the WM_QUERYENDSESSION message yet. In Figure 3, Notepad is blocking shut down but the custom MFC app is also shown (along with other applications that are still running) in the programs that are still running list, along with a reason why the application wants to block shut down.
Given all the work that has gone into Vista to make shut down more predictable and reliable, the addition of the new CancelShutdown API is surprising. When an application calls CancelShutdown while Vista is attempting to shut down, the shut down will be silently aborted. The OS provides no system dialogs or messages to identify the application that is blocking the shut down or to explain why the shut down was aborted. This is the same situation today when an application returns FALSE from a WM_QUERYENDSESSION handler.
The situation with CancelShutdown is also unpredictable. It depends on another application also blocking or returning FALSE to a WM_QUERYENDSESSION handler, which will bring up the dialog shown in Figure 1. In this case, the user can initiate shut down forcefully by clicking the Shut down now button. If the Vista shut down screen is not displayed before a call to CancelShutdown is made, the shut down will be silently terminated, with no notification to the user from the operating system about which application cancelled the shut down. The user can circumvent this by placing an application with unsaved data that behaves well during shut down (such as Notepad) as the top-most window and waiting for the system dialog to appear (which will occur after five seconds). At that time, the user can select the Shut down now button.
The Vista RTM release of the SDK documentation provides no guidance about when it would be appropriate to use CancelShutdown. Given it is not predictable whether the call will succeed, it doesn't appear wise to use it. Interestingly, Microsoft has pulled the online document of CancelShutdown, and the API may end up officially de-documented.
A Winning Document Recovery Strategy
The best strategy for an application to deal with operating system shut down is to periodically save a copy of the user's current data to a temporary location that can be recovered if the application is forcibly terminated during operating system shut down. The document recovery features of many Microsoft Office products is now familiar to most users, and they provide a good model of how document recovery should work.
For applications completing an operation that cannot be recovered when the operating system restarts, such as burning a CD, the new ShutdownBlockReasonXXX APIs should definitely be used to guarantee the user is given appropriate notification from the Vista shut down screen.
About the Author
Nick Wienholt is an independent Windows and .NET consultant based in Sydney, Australia. He is the author of Maximizing .NET Performance from Apress, and specializes in system-level software architecture and development with a particular focus on performance, security, interoperability, and debugging. Nick can be reached at NickW@dotnetperformance.com.