On .NET forums, I often come across people interested in knowing about notifications of something changed in the system. For example whether windows is shutting down, whether user is logging off, power mode changed, or system font changed etc. For instance, you may want to perform some operation when your application is terminating. In that case, what are all the possible ways of terminating the application?
- Closing the application by clicking close 'x' button
- Due to exception
- User kills the process
- When the user logs off or system shuts down
The first 2 are common scenarios which the user can take care of easily. But what about the 3rd and 4th cases? The 3rd case is, I don't think we can control. However, 4th one is interesting. When the system shutdown is started either by user or by any automated process, the shutdown process will terminate all running processes. Before that it sends a signal to all running processes that the system is going to shutdown. Upon receiving this signal, a process can do any windup operation so as to prevent any data loss. This is very important because you might be in middle of some important operation and sudden application termination may cause valuable data loss.
So, how do a .NET application receives this signal? Whenver it comes to the matter of system related things, many people think of native OS DLLs or PInvoke (some unmanaged way). But wait, we have some managed objects that do the work. There is a class called SystemEvents in Microsoft.Win32 dll which offers many system based events. You can google or refer MSDN for more info SystemEvents class. Here, I will just take an example of how System shutdown or user logoff events are handled.
Below is a simple console application that displays a message box whenever a system shutdown occurs or user logs off (In any case, it causes CLR to unload and hence a notification is sent about the event).
class Program
{
static void Main(string[] args)
{
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
Console.ReadLine(); //This is needed to keep the application running.
}
static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
{
switch (e.Reason)
{
case SessionEndReasons.Logoff:
MessageBox.Show("User logging off");
break;
case SessionEndReasons.SystemShutdown:
MessageBox.Show("System is shutting down");
break;
}
}
}