Software Development

How do I... Catch system level events in C#?


There are many instances when you may need to catch a system level event in C#. For instance, if your application is time sensitive, you may want to display a warning to the user if the system time is changed. You may also come upon a situation where you would like to be notified of changes to the display settings (resolution, color depth, etc...). In these instances, you can use the SystemEvents class of the .NET Framework.

The SystemEvents class lies within the Microsoft.Win32 namespace and has several static events that developers can attach to and use for notification of certain system level events. A list of these events is shown below:

·       DisplaySettingsChanged
·       DisplaySettingsChanging
·       EventsThreadShutdown
·       InstalledFontsChanged
·       PaletteChanged
·       PowerModeChanged
·       SessionEnded
·       SessionEnding
·       SessionSwitch
·       TimeChanged
·       TimerElapsed
·       UserPreferenceChanged
·       UserPreferenceChanging

This How do I... blog post will concentrate on the following events: DisplaySettingsChanged, SessionEnding, and TimeChanged.

This blog post is also available as a TechRepublic download, which includes a sample Visual Studio Project.

Subscribing to the events

The events on the SystemEvents class should be subscribed to just like any other event in the .NET Framework. Listing A demonstrates how to attach to any of the three events listed above:

Listing A

   private void Form1_Load(object sender, EventArgs e)

{

SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);

SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);

SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);

}

void SystemEvents_TimeChanged(object sender, EventArgs e)

{

this.txtResults.AppendText("Time has been changed!rn");

}

void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)

{

this.txtResults.AppendText("Session is ending!rn");

}

void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)

{

this.txtResults.AppendText("Display settings have changed!rn");

}

As you can see, the SystemEvents class makes accessing these events extremely easy. All we have to do is include the Microsoft.Win32 namespace in our code and we immediately have access to SystemEvents and its child events.

Canceling an event

There is one event within the SystemEvents class that you can cancel. This means that if the event is raised, you have the option to override the event and stop the event from being completed. The event with this ability is the SessionEnding event.

This event has a nonstandard event handle signature. An example of code that will always cancel this event is shown in Listing B.

Listing B

   private void Form1_Load(object sender, EventArgs e)

{

SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);

}

void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)

{

e.Cancel();

}

The SessionEndingEventArgs class also contains a property called "Reason" that can tell you exactly why the session is ending. This would allow you to cancel or allow the event based on the reason it was raised.

An important note on static events

When subscribing to a static event, it is important to remember to detach from the event before your application closes or the object subscribing to the event is disposed. Failing to do so can result in memory leaks for your application since the event subscription will not be broken automatically when the object closes.

Listing C shows how to use the FormClosing event on a windows form to accomplish this.

Listing C

  private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged);

SystemEvents.SessionEnding -= new SessionEndingEventHandler(SystemEvents_SessionEnding);

SystemEvents.TimeChanged -= new EventHandler(SystemEvents_TimeChanged);

}

The code in the listings is included in the sample project available with the download version of this blog post.

1 comments
hkarram
hkarram

How do I let a sound alert of Microsoft windows generate an e-mail or SMS ?