Monitoring Windows Services With C#
Tags: csharp, dotnet
Published: 2023-06-19 21:27:58

---
title: Monitoring Windows Services With C#
published: true
date: 2023-04-04 14:33:03 UTC
tags: csharp,dotnet
canonical_url: https://www.euantorano.co.uk/posts/2023/04/04/monitoring-windows-services-with-c/
---

Ever wanted to monitor the state of Windows Services in a .NET project? This is a problem I recently had to solve and after some experimentation I settled on using WMI to monitor changes.

This approach allows monitoring the start mode, state, process ID, and much more for any Windows Services on either a local or remote server.

To get started, you’ll need to install the `System.Management` NuGet package:

```
dotnet add package System.Management --version 7.0.0
```

Then it’s simply a case of using the `ManagementEventWatcher` class to monitor for intrinsic events where the target instance is of the type `Win32_Service`.

Note that there are a lot of other [event types](https://learn.microsoft.com/en-us/windows/win32/wmisdk/determining-the-type-of-event-to-receive) and [classes](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/operating-system-classes)that you can monitor with WMI – these are worth experimenting with too!

So how does this work? Let’s see an example:

```C#
using System.Management;

EventQuery query = new("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance isa \"Win32_Service\"");

using ManagementEventWatcher eventWatcher = new(query);
eventWatcher.EventArrived += EventArrived;

try
{
    eventWatcher.Start();

    Console.ReadLine();

    eventWatcher.Stop();
}
finally
{
    eventWatcher.EventArrived -= EventArrived;
}

static void EventArrived(object? sender, EventArrivedEventArgs e)
{
    if (e.NewEvent.GetPropertyValue("TargetInstance") is ManagementBaseObject instanceDescription)
    {
        using (instanceDescription)
        {
            foreach (PropertyData property in instanceDescription.Properties)
            {
                Console.WriteLine("{0}:: {1}", property.Name, property.Value);
            }

            Console.WriteLine();
        }
    }
}
```

This is a console app which starts watching for events, and whenever any instance event occurs it prints each property for the service that changed to the standard output. If you run this and then start/stop some services, you should see some output like the following:

```
AcceptPause:: False
AcceptStop:: False
Caption:: Background Intelligent Transfer Service
CheckPoint:: 0
CreationClassName:: Win32_Service
DelayedAutoStart:: True
Description:: Transfers files in the background using idle network bandwidth. If the service is disabled, then any applications that depend on BITS, such as Windows Update or MSN Explorer, will be unable to automatically download programs and other information.
DesktopInteract:: False
DisplayName:: Background Intelligent Transfer Service
ErrorControl:: Normal
ExitCode:: 0
InstallDate::
Name:: BITS
PathName:: C:\WINDOWS\System32\svchost.exe -k netsvcs -p
ProcessId:: 0
ServiceSpecificExitCode:: 0
ServiceType:: Share Process
Started:: False
StartMode:: Auto
StartName:: LocalSystem
State:: Stopped
Status:: OK
SystemCreationClassName:: Win32_ComputerSystem
SystemName:: COMPUTER-NAME
TagId:: 0
WaitHint:: 0
```

Actions such as changing the service start mode or the display name will also cause events to be raised too.

You can find all of the available properties by looking at the documentation for the `Win32_Service` class.