ZearaeZ
ZearaeZ

Reputation: 905

How to monitor windows services using c#

How can i monitor windows services using c# and i also have to save those services name, started time and services end time using in a CSV file. If any new services started than it should automatically write services name, started time and services end time using in existing CSV file.

Upvotes: 3

Views: 4801

Answers (2)

Narbs
Narbs

Reputation: 131

In case someone is looking for a solution to this in 2021, you can do this using a service controller, async task and the WaitForStatus() method:

Update: I realized my initial solution would not work so I rewrote it completely:

CLASS DEFINITION

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.ServiceProcess; // not referenced by default

public class ExtendedServiceController: ServiceController
{
    public event EventHandler<ServiceStatusEventArgs> StatusChanged;
    private Dictionary<ServiceControllerStatus, Task> _tasks = new Dictionary<ServiceControllerStatus, Task>();

    new public ServiceControllerStatus Status
    {
        get
        {
            base.Refresh();
            return base.Status;
        }
    }

    public ExtendedServiceController(string ServiceName): base(ServiceName)
    {
        foreach (ServiceControllerStatus status in Enum.GetValues(typeof(ServiceControllerStatus)))
        {
            _tasks.Add(status, null);
        }
        StartListening();
    }

    private void StartListening()
    {
        foreach (ServiceControllerStatus status in Enum.GetValues(typeof(ServiceControllerStatus)))
        {
            if (this.Status != status && (_tasks[status] == null || _tasks[status].IsCompleted))
            {
                _tasks[status] = Task.Run(() =>
                {
                    try
                    {
                        base.WaitForStatus(status);
                        OnStatusChanged(new ServiceStatusEventArgs(status));
                        StartListening();
                    }
                    catch
                    {
                        // You can either raise another event here with the exception or ignore it since it most likely means the service was uninstalled/lost communication
                    }
                });
            }
        }
    }

    protected virtual void OnStatusChanged(ServiceStatusEventArgs e)
    {
        EventHandler<ServiceStatusEventArgs> handler = StatusChanged;
        handler?.Invoke(this, e);
    }
}

public class ServiceStatusEventArgs : EventArgs
{
    public ServiceControllerStatus Status { get; private set; }
    public ServiceStatusEventArgs(ServiceControllerStatus Status)
    {
        this.Status = Status;
    }
}

USAGE

static void Main(string[] args)
{
    ExtendedServiceController xServiceController = new ExtendedServiceController("myService");
    xServiceController.StatusChanged += xServiceController_StatusChanged;
    Console.Read();

    // Added bonus since the class inherits from ServiceController, you can use it to control the service as well.
}

// This event handler will catch service status changes externally as well
private static void xServiceController_StatusChanged(object sender, ServiceStatusEventArgs e)
{
    Console.WriteLine("Status Changed: " + e.Status);
}

Upvotes: 4

Nils Lande
Nils Lande

Reputation: 889

You can list running services using ServiceController or ManagementObjectSearcher.

Here is a sample using the ManagementObjectSearcher :

using System.Management;

...

StringBuilder sb = new StringBuilder();
string format = "{0},{1},{2},{3},{4}";

// Header line
sb.AppendFormat(format, "DisplayName", 
                        "ServiceName", 
                        "Status", 
                        "ProcessId", 
                        "PathName");
sb.AppendLine();

ManagementObjectSearcher searcher = 
           new ManagementObjectSearcher("SELECT * FROM Win32_Service");

foreach( ManagementObject result in searcher.Get() )
{
    sb.AppendFormat(format, result["DisplayName"], 
                            result["Name"], 
                            result["State"], 
                            result["ProcessId"], 
                            result["PathName"]
                   );
    sb.AppendLine();
}

File.WriteAllText(
         @"C:\temp\ManagementObjectSearcher_services.csv", 
         sb.ToString()
);

For getting start and stop times it looks like you have to query the Windows Event Log.

This blog post show how you can monitor the event log to get notified when a service is stopped or started: https://dotnetcodr.com/2014/12/02/getting-notified-by-a-windows-service-status-change-in-c-net/

Upvotes: 2

Related Questions