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(); }
Another 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. If you want more information on worker threads you can have a look at my articles – Create a Worker Thread for your Windows Form in C# and Using the BackgroundWorker Component in C#.
I hope you found this useful. Thanks for reading.
Dave
Hi Dave,
all of your articles are nice. Please update me to the above email whenever new articles were posted.
Thanks, Dave. This was very helpful. I am also happy that I was able to run your tutorial without compiler errors. Just a quick question here… Is it possible to change the appearance or size of a windows form, let’s say the system “Date and time” properties page?
Hi,
I want to develope an application in C# which will keep records of when user logged in, for how much time user was inactive, loggoff time.
can you please suggest me on this.
Excellent example, thanks.
Have tried it, and runs nicely.
Yet, I wish to capture some additional system events, particularly a runtime language change event (I know I can poll the language, but I guess there must be a system event that occurs when the language is changed).
The general UserPreferenceChangedEventHandler does not react to runtime language change.
any idea?
Thanks