Requirements: Windows 10 1909 Build 18363, Visual Studio 2019 Version 16.6.1
The MSFT documentation on
SystemEvents gives a clear example of how to hook SystemEvents into a Windows Service, by creating a hidden Form. However, following the instructions exactly, I am not able to get any of the SystemEvents to log a message to the Event Viewer.
Does this no longer work? I am running Windows 10 1909 (Build 18363), using Visual Studio 19 Version 16.6.1.
Program.cs:
using System.ServiceProcess;
namespace WindowsServiceWithGuiTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
ProjectInstaller.cs:
using System.ComponentModel;
namespace WindowsServiceWithGuiTest
{
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
}
}
ProjectInstaller.Designer.cs 'InitializeComponent' method:
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.Description = "This is a test service that also launches a GUI which you can hook system events " +"into.";
this.serviceInstaller1.DisplayName = "ServiceWithGuiTest";
this.serviceInstaller1.ServiceName = "ServiceWithGuiTest";
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
Service1.cs:
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Windows.Forms;
namespace WindowsServiceWithGuiTest
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest", "Starting Service");
new Thread(RunMessagePump).Start();
}
void RunMessagePump()
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.MessagePump", "Starting Message Pump");
Application.Run(new HiddenForm());
}
protected override void OnStop()
{
Application.Exit();
}
public partial class HiddenForm : Form
{
public HiddenForm()
{
InitializeComponent();
EventLog.WriteEntry("WindowsServiceWithGuiTest.HiddenForm_FormClosing", "Form c'tor finished");
}
private void HiddenForm_Load(object sender, EventArgs e)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.DisplaySettingsChanged", "Form loaded");
SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);
SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UPCChanged);
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.DisplaySettingsChanged", "Display Settings Have changed");
}
private void HiddenForm_FormClosing(object sender, FormClosingEventArgs e)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.HiddenForm_FormClosing", "Form closing");
SystemEvents.TimeChanged -= new EventHandler(SystemEvents_TimeChanged);
SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(SystemEvents_UPCChanged);
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
}
private void SystemEvents_TimeChanged(object sender, EventArgs e)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.TimeChanged", "Time changed; it is now " +
DateTime.Now.ToLongTimeString());
}
private void SystemEvents_UPCChanged(object sender, UserPreferenceChangedEventArgs e)
{
EventLog.WriteEntry("WindowsServiceWithGuiTest.UserPreferenceChanged", e.Category.ToString());
}
}
partial class HiddenForm
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(0, 0);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "HiddenForm";
this.Text = "HiddenForm";
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
this.Load += new System.EventHandler(this.HiddenForm_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HiddenForm_FormClosing);
this.ResumeLayout(false);
}
}
}
}
When I compile, install, and start the service, then try to do something like change the time, change my desktop background, or change my display resolution, NOTHING HAPPENS! The last seen event log message is that the "Form loaded".
![]()
Any help would be greatly appreciated!
Tam