[.net] How can a windows service programmatically restart itself?

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

This question is related to .net windows windows-services windows-server-2003

The answer is


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?


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


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


const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

where SERVICENAME is the name of your service (double quotes included to account for spaces in the service name, can be omitted otherwise).

Clean, no auto-restart configuration necessary.


The problem with shelling out to a batch file or EXE is that a service may or may not have the permissions required to run the external app.

The cleanest way to do this that I have found is to use the OnStop() method, which is the entry point for the Service Control Manager. Then all your cleanup code will run, and you won't have any hanging sockets or other processes, assuming your stop code is doing its job.

To do this you need to set a flag before you terminate that tells the OnStop method to exit with an error code; then the SCM knows that the service needs to be restarted. Without this flag you won't be able to stop the service manually from the SCM. This also assumes you have set up the service to restart on an error.

Here's my stop code:

...

bool ABORT;

protected override void OnStop()
{
    Logger.log("Stopping service");
    WorkThreadRun = false;
    WorkThread.Join();
    Logger.stop();
    // if there was a problem, set an exit error code
    // so the service manager will restart this
    if(ABORT)Environment.Exit(1);
}

If the service runs into a problem and needs to restart, I launch a thread that stops the service from the SCM. This allows the service to clean up after itself:

...

if(NeedToRestart)
{
    ABORT = true;
    new Thread(RestartThread).Start();
}

void RestartThread()
{
    ServiceController sc = new ServiceController(ServiceName);
    try
    {
        sc.Stop();
    }
    catch (Exception) { }
}

Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

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


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?


Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

You can create a subprocess using Windows cmd.exe that restarts yourself:

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

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?


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.


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.


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.


Just passing: and thought i would add some extra info...

you can also throw an exception, this will auto close the windows service, and the auto re-start options just kick in. the only issue with this is that if you have a dev enviroment on your pc then the JIT tries to kick in, and you will get a prompt saying debug Y/N. say no and then it will close, and then re-start properly. (on a PC with no JIT it just all works). the reason im trolling, is this JIT is new to Win 7 (it used to work fine with XP etc) and im trying to find a way of disabling the JIT.... i may try the Environment.Exit method mentioned here see how that works too.

Kristian : Bristol, UK


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


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.


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


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();
        }
    }

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.


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.


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.


Just passing: and thought i would add some extra info...

you can also throw an exception, this will auto close the windows service, and the auto re-start options just kick in. the only issue with this is that if you have a dev enviroment on your pc then the JIT tries to kick in, and you will get a prompt saying debug Y/N. say no and then it will close, and then re-start properly. (on a PC with no JIT it just all works). the reason im trolling, is this JIT is new to Win 7 (it used to work fine with XP etc) and im trying to find a way of disabling the JIT.... i may try the Environment.Exit method mentioned here see how that works too.

Kristian : Bristol, UK


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


Create a separate appdomain to host the application code. When requires restart, we could unload and reload the appdomain instead the process (windows service). This is how IIS app pool works, they dont run asp.net app directly, they use separate appdmain.


The first response to the question is the simplest solution: "Environment.Exit(1)" I am using this on Windows Server 2008 R2 and it works perfectly. The service stops itself, the O/S waits 1 minute, then restarts it.


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.


The first response to the question is the simplest solution: "Environment.Exit(1)" I am using this on Windows Server 2008 R2 and it works perfectly. The service stops itself, the O/S waits 1 minute, then restarts it.


The problem with shelling out to a batch file or EXE is that a service may or may not have the permissions required to run the external app.

The cleanest way to do this that I have found is to use the OnStop() method, which is the entry point for the Service Control Manager. Then all your cleanup code will run, and you won't have any hanging sockets or other processes, assuming your stop code is doing its job.

To do this you need to set a flag before you terminate that tells the OnStop method to exit with an error code; then the SCM knows that the service needs to be restarted. Without this flag you won't be able to stop the service manually from the SCM. This also assumes you have set up the service to restart on an error.

Here's my stop code:

...

bool ABORT;

protected override void OnStop()
{
    Logger.log("Stopping service");
    WorkThreadRun = false;
    WorkThread.Join();
    Logger.stop();
    // if there was a problem, set an exit error code
    // so the service manager will restart this
    if(ABORT)Environment.Exit(1);
}

If the service runs into a problem and needs to restart, I launch a thread that stops the service from the SCM. This allows the service to clean up after itself:

...

if(NeedToRestart)
{
    ABORT = true;
    new Thread(RestartThread).Start();
}

void RestartThread()
{
    ServiceController sc = new ServiceController(ServiceName);
    try
    {
        sc.Stop();
    }
    catch (Exception) { }
}

You can create a subprocess using Windows cmd.exe that restarts yourself:

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

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();
        }
    }

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.


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.


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?


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.


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.


Create a restart.bat file like this

@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%

schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%

Then delete the task %taskname% when your %service% starts


const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

where SERVICENAME is the name of your service (double quotes included to account for spaces in the service name, can be omitted otherwise).

Clean, no auto-restart configuration necessary.


Create a separate appdomain to host the application code. When requires restart, we could unload and reload the appdomain instead the process (windows service). This is how IIS app pool works, they dont run asp.net app directly, they use separate appdmain.


Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to windows-services

Can't start Tomcat as Windows Service Error 1053 the service did not respond to the start or control request in a timely fashion How to solve "The specified service has been marked for deletion" error Service will not start: error 1067: the process terminated unexpectedly How to get all Windows service names starting with a common word? Windows service with timer Windows service on Local Computer started and then stopped error Windows service start failure: Cannot start service from the command line or debugger "Automatic" vs "Automatic (Delayed start)" How to install node.js as windows service?

Examples related to windows-server-2003

Multiple -and -or in PowerShell Where-Object statement Batch file to restart a service. Windows Error message: (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) Domain Account keeping locking out with correct password every few minutes What possibilities can cause "Service Unavailable 503" error? ORA-12505: TNS:listener does not currently know of SID given in connect descriptor (DBD ERROR: OCIServerAttach) how to get list of port which are in use on the server How do I 'svn add' all unversioned files to SVN? Windows command to get service status? How do I measure execution time of a command on the Windows command line?