views:

7239

answers:

11

I need to write robust code in .NET to enable a windows service (server 2003) to restart itself. What it the best way to so this? Is there some .NET API to do it?

+2  A: 

I don't think you can in a self-contained service (when you call Restart, it will stop the service, which will interrupt the Restart command, and it won't ever get started again). If you can add a second .exe (a Console app that uses the ServiceManager class), then you can kick off the standalone .exe and have it restart the service and then exit.

On second thought, you could probably have the service register a Scheduled Task (using the command-line 'at' command, for example) to start the service and then have it stop itself; that would probably work.

technophile
+1  A: 

I don't think it can. When a service is "stopped", it gets totally unloaded.

Well, OK, there's always a way I suppose. For instance, you could create a detached process to stop the service, then restart it, then exit.

T.E.D.
+2  A: 

You can't be sure that the user account that your service is running under even has permissions to stop and restart the service.

Greg Hewgill
+1  A: 

The better approach may be to utilize the NT Service as a wrapper for your application. When the NT Service is started, your application can start in an "idle" mode waiting for the command to start (or be configured to start automatically).

Think of a car, when it's started it begins in an idle state, waiting for your command to go forward or reverse. This also allows for other benefits, such as better remote administration as you can choose how to expose your application.

plamb
+32  A: 

Set the service to restart after failure (double click the service in the control panel and have a look around on those tabs - I forget the name of it). Then, anytime you want the service to restart, just call Environment.Exit(1) (or any non-zero return) and the OS will restart it for you.

TheSoftwareJedi
Simple solutions are the best solutions. Just did this to replace the existing "2nd process to periodically restart the first" setup.
geofftnz
+4  A: 

It would depend on why you want it to restart itself.

If you are just looking for a way to have the service clean itself out periodically then you could have a timer running in the service that periodically causes a purge routine.

If you are looking for a way to restart on failure - the service host itself can provide that ability when it is setup.

So why do you need to restart the server? What are you trying to achieve?

Brody
A: 

Is this what you're looking for? If you want to put this in the service, you needn't get the ServiceController.

public void RestartService(string name)
{
  ServiceController service = new ServiceController(name);
  service.Stop();
  Thread.Sleep(2500);
  service.Start();
  Thread.Sleep(2500);
}
ageektrapped
This cannot be used as a "self-restart" solution.
Isaac
+1  A: 

You can create a process that is a DOS command prompt that restarts yourself:

Process process = new Process(); process.StartInfo.FileName = "cmd"; process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\""; process.Start();

A: 

I would use the Windows Scheduler to schedule a restart of your service. The problem is that you can't restart yourself, but you can stop yourself. (You've essentially sawed off the branch that you're sitting on... if you get my analogy) You need a separate process to do it for you. The Windows Scheduler is an appropriate one. Schedule a one-time task to restart your service (even from within the service itself) to execute immediately.

Otherwise, you'll have to create a "shepherding" process that does it for you.

dviljoen
A: 

The easiest way is to have a batch file with:

net stop net start

and add the file to the scheduler with your desired time interval

A: 
private static void  RestartService(string serviceName)
    {
        using (var controller = new ServiceController(serviceName))
        {
            controller.Stop();
            int counter = 0;
            while (controller.Status != ServiceControllerStatus.Stopped)
            {
                Thread.Sleep(100);
                controller.Refresh();
                counter++;
                if (counter > 1000)
                {
                    throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
                }
            }

            controller.Start();
        }
    }
Lee Smith