How to Capture System Events using C#


What are system events? Well, basically they are events raised by the operating system when a user performs an action which affects the operating environment.

System events are accessible through the Microsoft.Win32.SystemEvents class.

SystemEvents Events
Below is a list of all the system events found within the SystemEvents class.

Name Description
DisplaySettingsChanged Occurs when the user changes the display settings.
DisplaySettingsChanging Occurs when the display settings are changing.
EventsThreadShutdown Occurs before the thread that listens for system events is terminated.
InstalledFontsChanged Occurs when the user adds fonts to or removes fonts from the system.
LowMemory Obsolete. Occurs when the system is running out of available RAM.
PaletteChanged Occurs when the user switches to an application that uses a different palette.
PowerModeChanged Occurs when the user suspends or resumes the system.
SessionEnded Occurs when the user is logging off or shutting down the system.
SessionEnding Occurs when the user is trying to log off or shut down the system.
SessionSwitch Occurs when the currently logged-in user has changed.
TimeChanged Occurs when the user changes the time on the system clock.
TimerElapsed Occurs when a windows timer interval has expired.
UserPreferenceChanged Occurs when a user preference has changed.
UserPreferenceChanging Occurs when a user preference is changing.

Note: Some of these system events may not be raised on Windows Vista.

Example Application
As an example let’s create a simple Windows Forms Application and place two buttons and a textbox on the main form. The buttons are going to subscribe and unsubscribe from the system events and the textbox is going to display the captured event details.

In our application we are going to listen for the following four system events: InstalledFontsChanged, DisplaySettingsChanged, TimeChanged, and UserPreferenceChanged. The code for this is shown below:

private bool eventHandlersCreated;

private void btnStartListening_Click(object sender, EventArgs e)
{
    this.StartListening();
}

private void btnStopListening_Click(object sender, EventArgs e)
{
    this.StopListening();
}

private void StartListening()
{
    Microsoft.Win32.SystemEvents.InstalledFontsChanged += new EventHandler(FontHandler);
    Microsoft.Win32.SystemEvents.DisplaySettingsChanged += new EventHandler(ScreenHandler);
    Microsoft.Win32.SystemEvents.TimeChanged += new EventHandler(TimeHandler);
    Microsoft.Win32.SystemEvents.UserPreferenceChanged += new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChangedHandler);

    this.eventHandlersCreated = true;
}

private void StopListening()
{
    Microsoft.Win32.SystemEvents.InstalledFontsChanged -= new EventHandler(FontHandler);
    Microsoft.Win32.SystemEvents.DisplaySettingsChanged -= new EventHandler(ScreenHandler);
    Microsoft.Win32.SystemEvents.TimeChanged -= new EventHandler(TimeHandler);
    Microsoft.Win32.SystemEvents.UserPreferenceChanged -= new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChangedHandler);

    this.eventHandlersCreated = false;
}

As you can see in the StartListening and StopListening methods we are subscribing and unsibscribing to the system events. Each event handler delegate is calling a particular method, and these methods are shown below:

private void FontHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("Installed fonts changed. {0}", Environment.NewLine);
}

private void PreferenceChangedHandler(object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e)
{
    txtStatus.Text += string.Format("You changed a setting: {0} {1}", e.Category.ToString(), Environment.NewLine);
}

private void ScreenHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("Screen resolution changed. {0}", Environment.NewLine);
}

private void TimeHandler(object sender, EventArgs e)
{
    txtStatus.Text += string.Format("System time changed. {0}", Environment.NewLine);
}

If you were to run this application and then go and change the screen resolution for example, the DisplaySettingsChanged event will fire and its delegate will call our ScreenHandler method, and you will see the text Screen resolution changed in the textbox.

Below is a screenshot of our application:

Note: Since these system events are static events, you must make sure you detach your event handlers when disposing your application, or you will end up with memory leaks!

To take care of this memory leak potential problem, when closing our application we are calling the StopListening method to unsubscribe from the event handlers.

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.eventHandlersCreated)
        this.StopListening();
}

Note: Do not perform time-consuming processing on the same thread that raises a system event handler because it might prevent other applications from functioning.

If your application must perform time-consuming processes, do the processing on a separate worker thread and not on the same thread which raises the system events.

Advertisements
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: