— Silvia
Hi Silvia.
Yes, both commands are adept at manipulating the state of a Windows Service. For example, both NET STOP and SC STOP will cause a service to shut down.
And both NET and SC are mature, stable and reliable utilities. Apparently Microsoft has worked out all the bugs over the past 30 years. 🙂
However, as far as developing batch files to start, stop and restart services, there is one subtle but important difference between the two utilities.
NET makes a request and waits to confirm…
When you issue a NET START or NET STOP command, NET.EXE:
Opens the Windows Service Control Manager (with OpenSCManager).
Opens the service (with OpenService).
Rejects the operation if the service is not in a compatible state. For example, if a stop was requested but the service is already stopped, an error is returned (likely exit code 2).
Requests that the service transitions to the appropriate state (with ControlService).
For the next 30 seconds:
Periodically checks the state of the service (with QueryServiceStatusEx).
Returns success (exit code 0) if the service transitions to the expected end state.
Keeps waiting if the service has not transitioned to the expected end state.
Returns an error if 30 seconds has elapsed but the service has not transitioned to expected end state.
… But SC simply makes a request and exits
On the other hand, when you run SC START or SC STOP command, SC.EXE:
Opens the Windows Service Control Manager (with OpenSCManager).
Opens the service (with OpenService).
Rejects the operation if the service is not in a compatible state. For example, if a stop was requested but the service is already stopped, an error is returned (likely exit code 2).
Requests that the service transitions to the appropriate state (with ControlService).
Returns success (exit code 0).
SC does not wait for the service to stop or start.
What the difference means for your batch files
Because SC does not wait for the service to transition to the desired state, you have to be careful when you use SC in batch files.
For example, to restart a service, this sequence looks like it should do the trick:
SC START ServiceName
And it works, for many services!
Indeed, here is the Print Spooler service quickly transitioning through the PENDING states and ending up running, as desired:
However, things go awry if the service takes a few seconds to stop.
For example, our CloudFileServer service takes 2-5 seconds to terminate (while it closes and uploads transient files to a remote site). The SC script doesn’t fare as well with that service:
As you can see, SC STOP succeeds and the service promptly transitions to the STOP_PENDING state. Unfortunately, the subsequent SC START fails with the “already running” error because the service is still shutting down — it has not yet stopped. And the final result (not pictured) is a dead service — the opposite of what we were hoping to achieve!
On the contrary, the equivalent sequence with the NET command worked much better:
However, NET will run into the same problem as SC if the service takes longer than 30 seconds to stop.
You should pause or confirm when using SC
Of course, you can have SC behave like NET by adding extra code to your script. For instance, adding the TIMEOUT command (which pauses for a fixed period) will give a slow service the chance to stop gracefully before attempting to restart it:
TIMEOUT /T 10
SC START CloudFileServer
This updated script works well with our CloudFileServer service:
Similarly, you can add code to check the state of the service (with the SC QUERY command) and react accordingly. That approach is more complicated, but it may be worth it in your situation.
Consider ServicePilot when working with slow or busy services
If you are working with services that take a while to start or stop, you should consider using our free ServicePilot command line utility.
Like NET.EXE, ServicePilot will wait to confirm the desired end state. However, ServicePilot allows you to specify the time to wait for the transition to complete.
Here is ServicePilot controlling SlowStopService — our internally developed service which can take up to a minute to stop:
Best of luck with your batch files!