How to simulate Windows shutdown for debugging?

C#.NetWinformsShutdown

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

There is a tool named Restart Manager (rmtool.exe) in the Microsoft's Logo Testing Tools for Windows, which can be used to send shutdown and restart messages to a process. Logo testing tools can be downloaded here:

http://download.microsoft.com/download/d/2/5/d2522ce4-a441-459d-8302-be8f3321823c/LogoToolsv1.0.msi

Then you can simulate shutdown for your process:

rmtool.exe -p [PID] -S

where [PID] is the process ID. According to the Vista Logo Certification Test Cases document,

> Restart Manager shutdown messages are: > > a. WM_QUERYENDSESSION with LPARAM = ENDSESSION_CLOSEAPP(0x1): GUI applications must respond (TRUE) immediately to prepare for a restart. > > b. WM_ENDSESSION with LPARAM = ENDSESSION_CLOSEAPP(0x1): The application must shutdown within 5 seconds (20 seconds for services). > > c. CTRL_SHUTDOWN_EVENT: Console applications must shutdown immediately.

Solution 2 - C#

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.

Solution 3 - C#

SendMessage can be used to send window messages with any parameters to a window.

> Very useful for debugging and testing.

  1. Send the message WM_QUERYENDSESSION with LPARAM = ENDSESSION_CLOSEAPP. The application must return 1 (TRUE) to indicate it's prepared to shut down and restart.

  2. Send the message WM_ENDSESSION with LPARAM = ENDSESSION_CLOSEAPP The application must shut down within the specified timeout period.

Solution 4 - C#

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:

Solution 5 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoryView Question on Stackoverflow
Solution 1 - C#dklView Answer on Stackoverflow
Solution 2 - C#Jon TackaburyView Answer on Stackoverflow
Solution 3 - C#Rami A.View Answer on Stackoverflow
Solution 4 - C#TarmoPikaroView Answer on Stackoverflow
Solution 5 - C#jamesmillerioView Answer on Stackoverflow