views:

739

answers:

6

We have a SmartClient built in C# that stubornly remains open when the PC its running on is being restarted. This halts the restart process unless the user first closes the SmartClient or there is some other manual intervention.

This is causing problems when the infrastructure team remotely installs new software that requires a machine reboot.

Any ideas for getting the SmartClient app to recognize the shutdown/restart event from Windows and gracefully kill itself?

UPDATE: This is a highly threaded application with multiple gui threads. yes, multiple gui threads. Its really a consolidation of many project that in and of themselves could be standalone applications - all of which are launched and managed from a single exe that centralizes those management methods and keeps track of those threads. I don't believe using background threads is an option.

A: 

Normally a .Net app would respond correctly- at least, that's the 'out of the box' behavior. If it's not, there could be a number of things going on. My best guess without knowing anything more about your program is that you have a long-running process going in the main UI thread that's preventing the app from responding to window messages.

Joel Coehoorn
Not long-running processes but do have Threading as Catalin mentioned above. Still, that doesn't really answer the question - I'm really looking for a way to detect when the machine is being restarted.
ScottCher
+1  A: 

Or maybe the .Net app is ignoring close or quit messages on purpose?

Hristo Deshev
this is a comment imo
Konstantinos
+5  A: 

It must be a thread that continues to run preventing your application to close. If you are using threading an easy fix would be to set it to background.

A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.

http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

Catalin DICU
Indeed, this is a threaded app. See update to original post. However, given what we're doing with the threads, is backgrounding them still viable? Ie, multiple GUI threads.
ScottCher
+5  A: 

OK, if you have access to the app, you can handle the SessionEnded event.

...
Microsoft.Win32.SystemEvents.SessionEnded +=new
  Microsoft.Win32.SessionEndedEventHandler(shutdownHandler);

...

private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
  // Do stuff
}
Vincent McNabb
Just a note: You probably want the SessionEndING event, not the SessionEnded (if you need to abort threads and close forms etc).
Sire
+1 for learning something new.
Ikaso
A: 

Background threads was a quick and dirty solution, best solution is to use synchronisation objects (ManualResetEvent, Mutex or someting else) to stop the other threads;

Or else keep track of all your opened windows and sent WM_CLOSE message when main app closes.

You have to give more information about how do you start those GUI applications. maybe you start one thread for each application and call Application.Run(new Form1()); ?

You may also look into creating a AppDomain for each GUI Application

Catalin DICU
+4  A: 

When a user is logging off or Windows is being shut down, WM_QUERYENDSESSION message is sent to all top-level windows. See MSDN documentation here.

The default behavior of a WinForm application in response to this message is to trigger the FormClosing event with CloseReason == WindowsShutDown or others. The event handler though can choose to be stubborn and refuse to shut the app down, thus keeping the system running.

Check FormClosing handlers of your applications. Maybe there is something in there. I've seen this kind of stuff a couple of times.

liggett78