How to simulate Windows shutdown for debugging?

Viewed 14280

I have an issue with my application when Windows shuts down - my app isn't exiting nicely, resulting in the End Task window being displayed. How can I use the debugger to see what's going on?

Is there a way to send the Windows shutdown message(s) to my application so it thinks Windows is shutting down, so I can see exactly how it behaves?

5 Answers

I believe when Windows is shutting down it sends a "WM_QueryEndSession" to all applications. To simulate a Windows shutdown you could create a little application that just does a PostMessage with this message to your application and see what happens. Windows may send more messages than that to actually close your application (like WM_CLOSE), but whenever your application receives the "WM_QueryEndSession" message it means your application is about to have the rug pulled out from under it.

This can be done using rmlogotest.exe tool. See following link:

https://superuser.com/questions/959364/on-windows-how-can-i-gracefully-ask-a-running-program-to-terminate#1154058

If you're using WPF, then you can handle additional event:

        Application.SessionEnding += Application_SessionEnding;

where you can set e.Cancel = true; to be able to abort application closure.

I think rmlogotest.exe uses timeout of 5 seconds and then it will tell you that LOGO Validation FAILED.

If you put some sort of message box confirmation in your application - you get failure as for end-user it will take probably more than 5 seconds to respond.

I guess from windows perspective if 5 seconds passed by, it want to reboot anyway - and if end-user hasn't saved his document / work - then windows is expecting to copy it somewhere else maybe.

From my perspective (as application developer) - it's acceptable to have failing LOGO Validation FAILED, as user can decide on it's own - whether he will kill my application after 5 seconds and looses his document or he will save the document and closes my application manually.

If you need to broadcast WM_QUERYENDSESSION message, then it needs to be sent via SendMessage to all windows in current process. Starting sample code can be found from here:

https://github.com/qakit/headless.git

But it sends only WM_ENDSESSION message, you need to use WM_QUERYENDSESSION instead and add windows enumeration of given process.

Related links:

You could use the SystemEvents.SessionEnding event, which is fired when a user logs off or shuts down. Be careful when using it though, some resources are not guaranteed to be available. For example, my application needed to hit a server when it was shutting down to clock a user out (a timeclock application), but the network card is sometimes already disabled when this event occurs. Since you're just doing cleanup, this should work fine.

Related