5 December 2011

Handling System Shutdown / Logoff events in C#.NET

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?
  1. Closing the application by clicking close 'x' button
  2. Due to exception
  3. User kills the process
  4. 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;
        }
    }
}

17 comments:

  1. This works only if the application is run by the logged on user. Otherwise it is not working.

    ReplyDelete
  2. From my limited understanding, it's possible to get around that by having a service with a hidden form so that the hidden form receives the notification like any other window so the user shouldn't matter... but I'm no coder so that could be complete bollocks. If it doesn't work that way, it should!

    Pat

    ReplyDelete
  3. Can i Cancel shutdown programmatically??? Need it hard

    Whole scenario is that I have evolution period of Win Server 2012 that restarts automatically after 1 hour, I want to override this behavior.

    ReplyDelete
  4. I am not sure of that. However, try executing below command.
    Process.Start("shutdown", "-a")

    ReplyDelete
  5. Thanx for quick response.........

    But that does not work for me ;-(

    ReplyDelete
  6. its not working on the windows 8 pc

    ReplyDelete
  7. Thanks for sharing wonderful blog. For .net training

    ReplyDelete
  8. Given so much information in it. its very useful .perfect explanation about Dot net framework.Thanks for your valuable information. dot net training in chennai velachery | dot net training institute in velachery

    ReplyDelete
  9. It is really a great work and the way in which u r sharing the knowledge is excellent.
    Thanks for helping me to understand basic concepts. As a beginner in Dot Net programming your post help me a lot.Thanks for your informative article.. dot net training and placement in chennai | best dot net training in chennai

    ReplyDelete
  10. Hai Author Good Information that i found here,do not stop sharing and Please keep updating us..... Thanks.
    hire asp.net developer
    .net development services

    ReplyDelete
  11. Thanks for sharing wonderful blog. But it works only when user is login except not work. Try to got .Net Training

    ReplyDelete
  12. It 's an amazing article and useful for developers
    .Net Online Training

    ReplyDelete