2

I'm writing an app to programmatically start/stop a Windows Service using ServiceController. I have a UI class that has some UI bells and whistles, and a Helper class that starts and stops the service.

In the Helper class:

void StopService()
{
    var controller = new ServiceController("MyService");

    if (controller.Status == ServiceControllerStatus.Running)
    {
      controller.Stop();
      controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 60));
    }
}

In the UI class:

Helper.StopService();

var controller = new ServiceController("MyService");

if (controller.Status == ServiceControllerStatus.Stopped)
{
    // Do some stuff
}
else
{
    // MyService not stopped. Explode!
}

The problem is that when the service is stopping, the method in Helper immediately returns to the caller in UI class, without waiting the service to reach stopped (the service is eventually stopped after about 5-10 seconds). If I move the start/stop logic to the UI class, things got normal.

What silly mistake am I making here?

Jim
  • 1,695
  • 2
  • 23
  • 42
  • Any chance the service is in a state other than running or stopped when StopService() is called? For example, start pending or stop pending? (You can check from the command line with `sc status`.) – Harry Johnston Jun 23 '15 at 22:56
  • In my tests I made sure (sc status) the service was running before calling the StopService(). Also the service is actually being stopped (and eventually stopped) - just StopService() returned early to the caller before WaitForStatus() is completed. – Jim Jun 24 '15 at 05:35

1 Answers1

1

Instead of ServiceController.WaitForStatus() you could use a delay/refresh loop as shown on MSDN in ServiceController Class but a better way would probably be using an Async wait for status like that detailed in this answer.

sc.Stop();
while (sc.Status != ServiceControllerStatus.Stopped)
{
    Thread.Sleep(1000);
    sc.Refresh();
}
Community
  • 1
  • 1
John Kaster
  • 2,509
  • 1
  • 33
  • 40