56

I am having an issue with an application that I am creating. I am trying to start a windows service through my C# app. When I click my start button, it looks like everything goes through but when I log into the server, the service still does not show that it is running. However, the second time I run it, I get an exception that says the instance of the service is already running. Again when I log into the server, the service appears to be stopped. Has anyone ever seen this?

Here is my code.

try
{
    while (reader.Read())
    {
        int timeoutMilliseconds = 1000;
        string serviceName = reader["ServiceName"].ToString();
        string permission = reader["Permission"].ToString();

        if (permission == "E")
        {
            lblServStartSuccess.Visible = true;

            ServiceController service = new ServiceController(serviceName);
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

            service.Start();
            service.WaitForStatus(ServiceControllerStatus.Running, timeout);
        }
        else
        {
            lblServErrorStart.Visible = true;
        }
    }
}
catch (Exception ex)
{
    Response.Write(ex.ToString());
}

EDIT: Here is the exception I received on one service:

System.InvalidOperationException: Service Logical Disk Manager Administrative Service was not found on computer '.'. ---> System.ComponentModel.Win32Exception: The specified service does not exist as an installed service --- End of inner exception stack trace

I know the service exists. Do I need to add something in front of the service to tell it what server to look at?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Matt
  • 1,220
  • 3
  • 21
  • 36
  • 2
    Are you sure the service isn't stuck in the starting state? I remember the services control panel wasn't brilliant about showing that (at least some windows version ago) – Rup Jul 12 '11 at 16:40
  • what do you mean with "when I log into the server" - are you trying to use the SCM on a different machine? – BrokenGlass Jul 12 '11 at 16:40
  • Yes I am running the web service from a remote server. I am using an account that has admin access. I am not sure if it is stuck. Could my timeout be too short and it is timing out? – Matt Jul 12 '11 at 16:41
  • Oh and both systems in question are running Server 2003. – Matt Jul 12 '11 at 16:44
  • 4
    1 second is pretty short for a remote service start. Change it to 60 seconds and see if that makes a difference. – Samuel Neff Jul 12 '11 at 17:01
  • I removed the timeout and same issue. Everything appears to be working. The service just does not show as Started. – Matt Jul 12 '11 at 18:23
  • This might be stating the obvious, but are you sure the service you are trying to start is installed on the machine which you are trying to start it on? – Merav Kochavi Jan 26 '16 at 06:03

6 Answers6

44

If the code you showed is executing on a different machine than where the service is supposed to run (I'm not clear from your comments if that's the case or not), you would need to provide the machine name in the ServiceController constructer.

Is it possible you are successfully starting the service, but not on the machine you think? That would fit the symptoms you describe.

ServiceController service = new ServiceController(serviceName, serverName);

Also see ServiceController constructor documentation.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • I've edited to show the use of the constructor that takes the remote server name. – hatchet - done with SOverflow Jul 12 '11 at 20:04
  • I think you were correct because now I am getting an error saying that other privileges are required to do this. – Matt Jul 12 '11 at 20:12
  • If I log in as the impersonated user to the source server, I can pull up the service manager of the target server and remotely start and stop services. I just can't do it from the web app. – Matt Jul 12 '11 at 20:22
  • 1
    It may depend on how you have your web app security set up, but I think the account the web app's app pool is running under will need rights to start/stop services on the machine where the services are to be run. – hatchet - done with SOverflow Jul 12 '11 at 20:30
  • I had commented out my impersonation. I need to pay more attention. Works great now. Thank you very much. – Matt Jul 12 '11 at 20:33
21

Here is code I have in a Window Service responsible for stopping starting other services running on the same server.

ServiceController controller = new ServiceController(serviceName);
if (controller.Status==ServiceControllerStatus.Running)
    controller.Stop();

if (controller.Status==ServiceControllerStatus.Stopped)
    controller.Start(); 
Gary Kindel
  • 17,071
  • 7
  • 49
  • 66
8

This is an old thread, but google got me here. My services, even after successfully starting, would still query back as stopped. If you add

service.Refresh();

It will query the actual current status instead of the stored state from a previous query. I don't know why it works like this, but it does.

P.S.: I added a minute long time out and still got a service is stopped response without the refresh.

Jamel Toms
  • 4,525
  • 2
  • 27
  • 26
MattyMatt
  • 531
  • 5
  • 21
6
public static void StartService(string serviceName, int timeoutMilliseconds)
    {
        ServiceController service = new ServiceController(serviceName);
        try
        {
            int millisec1 = 0;
            TimeSpan timeout;

            // count the rest of the timeout
            int millisec2 = Environment.TickCount;
            timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec1));
            service.Start();
            service.WaitForStatus(ServiceControllerStatus.Running, timeout);

        }
        catch (Exception e)
        {
            Trace.WriteLine(e.Message);
        }
    }
    public static void StopService(string serviceName, int timeoutMilliseconds)
    {
        ServiceController service = new ServiceController(serviceName);
        try
        {
            int millisec1 = 0;
            TimeSpan timeout;
            if (service.Status == ServiceControllerStatus.Running)
            {
                millisec1 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
            }


        }
        catch (Exception e)
        {
            Trace.WriteLine(e.Message);
        }
    }
    public static void RestartService(string serviceName, int timeoutMilliseconds)
    {
        ServiceController service = new ServiceController(serviceName);
        try
        {
            int millisec1 = 0;
            TimeSpan timeout;
            if (service.Status == ServiceControllerStatus.Running)
            {
                millisec1 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
            }
            // count the rest of the timeout
            int millisec2 = Environment.TickCount;
            timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
            service.Start();
            service.WaitForStatus(ServiceControllerStatus.Running, timeout);

        }
        catch (Exception e)
        {
            Trace.WriteLine(e.Message);
        }
    }

Dont forget to add ServiceProcess as referance using System.ServiceProcess;

Nikhil Dinesh
  • 3,359
  • 2
  • 38
  • 41
2

First of all you need to add reference of the DLL (ServiceProcess) in your project References as like:

Right click on References in Solution Explorer -> Add Reference -> Assemblies -> 
Framework -> System.ServiceProcess

Then add ServiceProcess DLL in your project:

using System.ServiceProcess;

After that use this code:

ServiceController service = new ServiceController(yourServiceName);
  • 2
    From the code in the question I think the OP had already got past that point. – Rup Jul 02 '18 at 10:11
0

Just try service.Start(); without the timeout or waitforstatus and hook its events to see whats happening.

tcables
  • 1,231
  • 5
  • 16
  • 36