Halt batch file until service stop is complete?
Asked Answered
M

7

44

I'm using a batch file to stop a Windows service. I'm using the sc command, but I'm open to other ideas, given the question below. The problem is that the batch file proceeds while the service is stopping (the stop argument to sc seems only to request the stop -- it doesn't wait for the stop).

How can I modify the batch file to not proceed until the stop is complete?

Mentally answered 20/5, 2010 at 14:54 Comment(0)
S
38

You can use NET stop, which is synchronous, i.e it will wait until the service stops.

See - NET stop

Spiegel answered 20/5, 2010 at 15:0 Comment(4)
However net stop will throw a general error code 2 (access denied) if the service is already stopped.Amoreta
This is not entirely correct. If the service takes, say 4 minutes, to actually fully stop and exit, the "net stop" command will return after 20-40 seconds, but the service process has not yet terminated. It returns "The service could not be stopped"... but this is misleading. The service HAS been sent a stop command, but just has not exited all the way within the SCM timeout.Gibbons
I know this thread is old but I just tested this on Windows Server 2012 R2 - I have a service that it takes about three minutes to stop... when running 'net stop' the command doesn't complete until the service executable has actually stopped and disappeared from task manager before the CMD file completes. It works on an updated server contrary to some of the older comments saying that it doesn't.Antin
After net stop returns, if you check the status using sc query "My Service Name" | find "STATE" some services can be in STOP_PENDING stateBaird
I
36
sc stop webdriveservice
:loop
sc query webdriveservice | find "STOPPED"
if errorlevel 1 (
  timeout 1
  goto loop
)

Another version with a repetition count limit:

sc stop webdriveservice
set count=1
set limit=10
:loop
sc query webdriveservice | find "STOPPED"
if errorlevel 1 (
  timeout 1
  set /a count += 1
  if %count% lss %limit% goto loop
)
Import answered 25/10, 2016 at 20:58 Comment(3)
Excellent answer. Just a question : why TIMEOUT and not SLEEP ? TIMEOUT would be bypassed by a keypress, and I don't think this is a desirable effect in a batch file (it's easy to press a key by error while having focus on the cmd window).Loredo
Actually, it's part of the 2003 Resource Kit. I thought it was in the standard Windows installation, my bad.Loredo
timeout 5 /nobreak will exit only on CTRL+CBaird
G
14

As mentioned above, NET STOP will send a stop command to the service, but, if the service takes more than a certain time (20 seconds or so is my observation), NET STOP will NOT wait for the service to actually stop before returning.

To actually pause the batch file until the service stops, you need to use an approach like those outlined in these threads:

How to check if a service is running via batch file and start it, if it is not running?

Stopping/Starting a remote Windows service and waiting for it to open/close

Gibbons answered 7/8, 2013 at 18:36 Comment(4)
Not the downvoter (although I can guess who was), but this answer is also contains wrong information. NET STOP will wait for the service to stop, up to a point. I've never had a service try stopping for the entire four minutes, so I can't say how long NET STOP waits, but it does wait a decent period of time, as opposed to sc stop.\Galactose
@LittleBobbyTables The post has been updated to account for what you observe. If you look at what the microsoft team writes (link below), you will see that the SCM only talks to one service at a time, so it won't wait forever for any one service. NET SEND is just a way to send a cmd to SCM, same as in service manager. blogs.msdn.com/b/bclteam/archive/2009/02/19/…Gibbons
Pulling out a little bit more information from the blog linked by @Jonesome: the registry key that controls the timeout is HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout. The default is apparently 20 seconds, but is 5 seconds on my Windows 8.1 Enterprise box (potentially altered by group policy).Fenton
@Fenton on Windows 2012 I set my HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout to DWORD 120000 and it had absolutely no effect - the net stop still returned after 10-15s even though the services is shutting down but hasn't stopped, won't stop for another 45sAbana
G
3

I believe net stop [Service] should wait until the service has fully stopped before moving on. sc stop [Service] simply sends a "stop" message to the service.

Galactose answered 20/5, 2010 at 15:3 Comment(3)
@Jonesome - instead of downvoting, why not provide a better answer?Galactose
fair call! Done! The reason to downvote is that both answers are contain wrong info (I tested on win7 and win2008, and know from experience that XP and other vers would behave the same).Gibbons
This is not entirely correct. If the service takes, say 4 minutes, to actually fully stop and exit, the "net stop" command will return after 20-40 seconds, but the service process has not yet terminated. It returns "The service could not be stopped"... but this is misleading. The service HAS been sent a stop command, but just has not exited all the way within the SCM timeout. –Putrescine
D
2

I had a similar issue with net stop. It returns when the service is indeed stopped, but the executable may still be running.
For upgrade reasons, this is not good enough, we need to wait until the process has finished.

I've used a simple loop to wait until the service executable has actually finished:

net stop "ServiceName"
:loop1
set _CmdResult=""
for /f "tokens=1" %%a in ('TASKLIST ^| FINDSTR ServiceName.exe') do set _CmdResult=%%a
if not %_CmdResult% == ""  (
  timeout 5
  goto loop1
)

Once the the executable finishes, the loop will break.

Declinometer answered 14/12, 2020 at 11:43 Comment(0)
W
1

This is a bit crude but it worked for me in order to ensure that I could schedule a daily batch file to essentially RESTART a service.

NET STOP [Service]

:TryAgain

TIMEOUT /T 10 /NOBREAK

NET START [Service]

IF %ERRORLEVEL% NEQ 0 GOTO TryAgain

I realize with this code snippet that this could result in an endless loop if the service was to not successfully start. I just wanted to basically show how to get around the issue using TIMEOUT where a service may take longer to stop than what the NET STOP command allows.

Whiny answered 1/7, 2015 at 20:7 Comment(0)
M
-1

Use the && symbol between commands. The && symbol waits to finish the previous command before proceed to next command.

All commands must be at the same command row. You can use as many commands you want in a row.

You can use also the pause command. With this, asks to press any key, before proceed to next procedure.

For example:

sc qdescription "MyServiceName" && echo. && sc stop "MyServiceName" && echo. && echo          [ "MyServiceName" service stopped ] && echo. && pause
Meneau answered 30/11, 2016 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.