What's New in 5.0.17595?

All right, my apologies. Apparently you have been working diligently on this for some time.

Let me ask some followup questions. I do this, becasue as a (retired) programmer and DBA, I sometimes found it very helpful to have a “fresh set of eyes” looking over a problem I may have been having.

When a human user tells eM Client to Close itself, there seems to be no problem. To me, it seems like eM Client closes very quickly. I haven’t run Task Manager while doing this to see how quickly all of the processes associated with eM Client – you mention NET Framework code – leave. Are you saying that these processes take so long to leave that they would be aborted by a Windows system-wide shutdown request?

I ask, because I really wonder whether you have tried to just duplicate a user’s manual shutdown request when Windows asks all programs to shut down. Of course, you would have to add some global switch while doing this, such that you would answer your own questions (e.g., “Do you want to shut down eM Client now, while you’re in the middle of sending a message?”), such that eM Client would leave as quickly as possible.

Second, is there no response you can give Windows, that says something like, “I’m working on this – just give me one more second, please”? I realize that Windows has limits on its patience, but know nothing more about this process; on the other hand, it’s pretty rare for programs to have a problem leaving, when Windows tells them to; eM Client is definitely an exception to that.

There are so many Windows users who have Windows Update set to update and, if necessary, restart their systems automatically that this issue shouldn’t be hanging around for YEARS, even if it is essentially Microsoft’s fault. I really think you need some fresh eyes on this.

Speaking as a programmer, there are two underlying problems. Most of the time we spent on this issue was diagnosing the first one… Let’s describe both. The first case is that we have some window open and visible, the second case is when we don’t (eg. the application is minimized to tray area and no windows are visible).

When the system is about to shut down it sends two messages to each top-level window. The first message (WM_QUERYENDSESSION) tells the application that the system is preparing to shutdown and asks the application if it should proceed. The second message (WM_ENDSESSION) tells the application that the everyone acknowledged the shut down and it’s happening now. For the second message we employ largely the same logic as if the window was closed by the user. Normally there’s pretty long grace period for processing this message before Windows kills the application, but due to a bug our application was getting killed early. The bug is actually pretty subtle and exposes an undocumented behavior of Win32 API. The .NET Framework handles the WM_ENDSESSION message in the same code path as the WM_CLOSE message (eg. window closed by user interaction) by notifying our application by calling OnClose method and then it destroying the window. It’s perfectly correct to destroy the window in response to WM_CLOSE message. However, in the case of WM_ENDSESSION the system waits for the message to be processed and destroing the window is treated as a failure indistinguishable from timeout to the calling process - the one that handles system shutdown. And the error results in the application being killed by the process handling the shutdown. This still wouldn’t be a problem if there was only one window since the shutdown code would run normally and only then the application would get forcefully killed. In our case there are usually more windows involved (main application window, popup notifications, Operations window, new mail windows, etc.) and the order in which the messages are delivered to these windows is non-deterministic (from our POV). The usual scenario with the bug was that a notification window received the WM_ENDSESSION message and it processed it, then .NET Framework destroyed the window and the shut down process identified it as timeout. Meanwhile we started processing the WM_ENDSESSION message delivered to the main window, but we got forcefully killed before the processing could finish.

The second case is when there are no windows involved. I don’t know the specifics for that case, but it has changed between Windows XP and Windows Vista. On newer systems we have to explicitly call some APIs to give us a little bit more time.

Filip: thank you for the thorough explanation and for your time. I guess I’ll just shut up about this issue for the forseeable future, and wish you luck. In the meantime, I’ve told Windows Update (which is the only thing that shuts down my very stable system by itself) to wait for my permission to install patches.