188

I have an application in C# (2.0 running on XP embedded) that is communicating with a 'watchdog' that is implemented as a Windows Service. When the device boots, this service typically takes some time to start. I'd like to check, from my code, if the service is running. How can I accomplish this?

Adrian Toman
  • 10,902
  • 5
  • 44
  • 60
edosoft
  • 16,270
  • 24
  • 75
  • 108
  • 1
    Please have a look on the [ServiceController](http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller(VS.80).aspx) object in .NET. – Larry Oct 07 '08 at 12:08
  • Oooh...even better than rolling your own via WMI. I'll remove my answer. – EBGreen Oct 07 '08 at 12:12
  • @EBGreen - I don't know, the WMI route may be useful for someone else in future, there's more than one way to skin a cat, and all that.... – Carl Oct 07 '08 at 12:16
  • Ya, but I really do think ServiceController is better over all, so I think I will leave it deleted. I never would have even suggested WMI if I hadn't just woken up. :) – EBGreen Oct 07 '08 at 12:17

2 Answers2

374

I guess something like this would work:

Add System.ServiceProcess to your project references (It's on the .NET tab).

using System.ServiceProcess;

ServiceController sc = new ServiceController(SERVICENAME);

switch (sc.Status)
{
    case ServiceControllerStatus.Running:
        return "Running";
    case ServiceControllerStatus.Stopped:
        return "Stopped";
    case ServiceControllerStatus.Paused:
        return "Paused";
    case ServiceControllerStatus.StopPending:
        return "Stopping";
    case ServiceControllerStatus.StartPending:
        return "Starting";
    default:
        return "Status Changing";
}

Edit: There is also a method sc.WaitforStatus() that takes a desired status and a timeout, never used it but it may suit your needs.

Edit: Once you get the status, to get the status again you will need to call sc.Refresh() first.

Reference: ServiceController object in .NET.

Carl
  • 5,405
  • 4
  • 23
  • 23
  • 11
    ServiceController.GetServices() retrieves a array that contains all the installed service as ServiceController object. This may help a lot. – Larry Oct 07 '08 at 12:13
  • Good call, I don't know if I've ever used that. Even if you never use it, I guess that it would be useful for debugging if nothing else – Carl Oct 07 '08 at 12:18
  • 9
    Add reference to System.ServiceProcess and add the statement: using System.ServiceProcess; – NealWalters Dec 17 '09 at 14:50
  • 6
    If I passed a bad service name, it seemed to lock up instead of throwing an error. I added this code: catch (System.Exception ex) { return "Not found"; } – NealWalters Dec 17 '09 at 16:19
  • 6
    NealWalters: How do you know the exception was thrown just because the service was not found? Isn't there a more suitable exception type to catch? – Patrik Svensson Feb 05 '10 at 14:27
  • 3
    private static bool ServiceExists(string serviceName) { return ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == serviceName) != null; } – Dmitry Pavlov Aug 15 '13 at 19:03
  • By the way `SERVICENAME` would be equal to the `ServiceName` property on the installer used for the service. If it matches your project name, an easy shortcut is to just use `this.ServiceName` – atconway Feb 19 '14 at 22:51
  • What's has more performance: new ServiceController(svcName) or ServiceController.GetServices().FirstOrDefault ? – Kiquenet Jun 09 '14 at 10:52
  • and you need to add a reference to this assembly: ServiceProcess – max Aug 18 '14 at 23:42
  • I found that I had to add more generic exception catches for when services did not exist. – SharpC Mar 19 '18 at 09:18
  • I've rolled back the changes that were made to this answer, because it should have been a new answer, rather than a full replacement for an existing answer with 300 votes. – Carl Jun 28 '18 at 13:07
16

Here you get all available services and their status in your local machine.

ServiceController[] services = ServiceController.GetServices();
foreach(ServiceController service in services)
{
    Console.WriteLine(service.ServiceName+"=="+ service.Status);
}

You can Compare your service with service.name property inside loop and you get status of your service. For details go with the http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller.aspx also http://msdn.microsoft.com/en-us/library/microsoft.windows.design.servicemanager(v=vs.90).aspx

Chin
  • 16,446
  • 27
  • 96
  • 148
rhatwar007
  • 335
  • 3
  • 14
  • This has a weak performance because you would have to loop over each and every service that's currently installed on the system in search for a single service. I recommend using this https://stackoverflow.com/a/178162/5262734 – Minasie Shibeshi Aug 25 '20 at 07:22