通过批处理或cmd文件停止和启动服务?

313

我该如何编写批处理或命令脚本来可靠地停止和启动服务,并进行错误检查(或者让我知道无论出于什么原因它都不成功)?

18个回答

359
使用 SC(服务控制)命令,它提供了比 startstop 更多的选项。
描述:
       SC 是一个用于与NT服务控制器和服务通信的命令行程序。
用法:
       sc <server> [command] [service name]  ...
选项 <server> 的格式为 "\\ServerName"。 可以通过键入 "sc [command]" 来获取有关命令的更多帮助。 命令: query-----------查询服务的状态,或枚举服务类型的状态。 queryex---------查询服务的扩展状态,或枚举服务类型的状态。 start-----------启动服务。 pause-----------发送暂停控制请求到服务。 interrogate-----发送询问控制请求到服务。 continue--------发送继续控制请求到服务。 stop------------发送停止请求到服务。 config----------更改服务的配置(持久性)。 description-----更改服务的描述。 failure---------更改服务在失败时执行的操作。 qc--------------查询服务的配置信息。 qdescription----查询服务的描述。 qfailure--------查询服务在失败时执行的操作。 delete----------删除服务(从注册表中)。 create----------创建服务(将其添加到注册表中)。 control---------向服务发送控制。 sdshow----------显示服务的安全描述符。 sdset-----------设置服务的安全描述符。 GetDisplayName--获取服务的DisplayName。 GetKeyName------获取服务的ServiceKeyName。 EnumDepend------枚举服务依赖项。
以下命令不需要服务名称: sc <server> <command> <option> boot------------(ok | bad) 指示上次启动是否应保存为最后已知的良好启动配置 Lock------------锁定“服务数据库” QueryLock-------查询“SCManager数据库”的锁定状态 示例: sc start MyService

1
我认同这比 net start/stop 更好。请注意,还有一个选项可以操作远程机器上的服务。 - Tim Frey
1
很好的答案,但你需要是管理员才能运行“SC start service”。我在这里找到了一个解决方案:[http://superuser.com/questions/419194/is-there-a-way-to-allow-standard-users-to-restart-stop-start-the-print-spooler(被接受的答案包含解决方案)]。 - Michael K.
66
SC命令存在的问题是它会立即返回而不是在操作完成后返回。如果您想通过批处理文件重新启动服务(先停止再启动),停止会立即返回,然后启动失败,因为服务没有停止。Net stop/start会在操作完成后返回,因此不会出现这个问题。 - Dom
5
2020 年有没有一种方法可以检查服务是否已经正确停止? - Anand Varkey Philips

233
net start [serviceName]

并且

net stop [serviceName]

告诉你他们是否成功或失败得相当清晰。例如

U:\>net stop alerter
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

如果从批处理文件中运行,您可以访问返回代码的ERRORLEVEL。 0表示成功。任何大于0的值表示失败。

作为bat文件,error.bat

@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause

输出结果如下:

U:\>error.bat
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

There was a problem
Press any key to continue . . .

返回代码

 - 0 = Success
 - 1 = Not Supported
 - 2 = Access Denied
 - 3 = Dependent Services Running
 - 4 = Invalid Service Control
 - 5 = Service Cannot Accept Control
 - 6 = Service Not Active
 - 7 = Service Request Timeout
 - 8 = Unknown Failure
 - 9 = Path Not Found
 - 10 = Service Already Running
 - 11 = Service Database Locked
 - 12 = Service Dependency Deleted
 - 13 = Service Dependency Failure
 - 14 = Service Disabled
 - 15 = Service Logon Failure
 - 16 = Service Marked For Deletion
 - 17 = Service No Thread
 - 18 = Status Circular Dependency
 - 19 = Status Duplicate Name
 - 20 = Status Invalid Name
 - 21 = Status Invalid Parameter 
 - 22 = Status Invalid Service Account
 - 23 = Status Service Exists
 - 24 = Service Already Paused

编辑于 2015年04月20日

返回代码:

NET命令不会返回 Win32_Service 类文档中列出的返回代码(例如:服务未激活、服务请求超时等),对于许多错误情况,它只会返回错误等级2。

可查看:http://ss64.com/nt/net_service.html


1
.NET 不仅仅适用于服务相关的功能,而 SC 则仅适用于服务相关的功能。 - Wernight
3
这个答案更好,因为"net"命令会阻塞并等待服务启动或停止后才继续执行批处理脚本。 - Steven
1
由于(正如编辑所说)大多数情况下返回的errorlevel是2,请在此处查看如何解释错误结果 - OfirD

29

您可以使用NET START命令,然后检查ERRORLEVEL环境变量,例如:

net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%

声明: 我是凭记忆写的,但我认为它会有效。


10

我已经为此创建了我的个人批处理文件,它与其他的有些不同,但请随意根据您的需求进行修改。 我之前闲来无事时创建了这个批处理文件,因为我希望为人们提供一个简单的方式来输入结束、开始、停止或设置为自动。此BAT文件只需请求您输入服务名称,其余的就交给它了。我没有意识到他在寻找某种表述任何错误的东西,可能是我误读了那一部分。尽管通常可以通过在行末输入>>输出.txt来完成这项工作。

%var% 只是为用户提供一种方法,让他们能够将自己的服务输入到其中,而不必每次启动/停止不同的服务时都去修改批处理文件。

如果我错了,任何人都可以随意纠正我。

@echo off
set /p c= Would you like to start a service [Y/N]?
  if /I "%c%" EQU "Y" goto :1
  if /I "%c%" EQU "N" goto :2
    :1  
    set /p var= Service name: 
:2 
set /p c= Would you like to stop a service [Y/N]?
  if /I "%c%" EQU "Y" goto :3
  if /I "%c%" EQU "N" goto :4
    :3  
    set /p var1= Service name:
:4
set /p c= Would you like to disable a service [Y/N]?
  if /I "%c%" EQU "Y" goto :5
  if /I "%c%" EQU "N" goto :6
    :5  
    set /p var2= Service name:
:6 
set /p c= Would you like to set a service to auto [Y/N]?
  if /I "%c%" EQU "Y" goto :7
  if /I "%c%" EQU "N" goto :10
    :7  
    set /p var3= Service name:
:10
sc start %var%
sc stop %var1%
sc config %var2% start=disabled
sc config %var3% start=auto

2
通常,仅有代码的回答不被重视。您能否详细说明您的解决方案或添加一些解释性注释? - James Parsons
3
我之前因为无聊想简单地让人们能够输入结束、开始、停止或自动设置,所以创建了这个BAT文件。它会要求你输入服务名称,然后就会自动完成剩下的步骤。 - Nathanial Wilson

10

与其检查代码,这种方法同样可行

net start "Apache tomcat" || goto ExitError

:End  
exit 0  

:ExitError  
echo An error has occurred while starting the tomcat services  
exit 1  

7

在我看来,使用net startnet stop返回的代码似乎是最好的方法。请参考此链接:Net Start return codes


2
链接页面已不存在。因此,现在这更像是一条评论。 - Victor Zakharov

7

语法总是让我困扰...所以...

这里明确说明如何在批处理文件中添加一行代码,以便在您是两台机器的管理员、以管理员身份运行.bat文件并且这两台机器在同一个域上时,可以杀死远程服务(在另一台机器上)。机器名称遵循UNC格式\myserver

sc \\ip.ip.ip.ip stop p4_1

在这种情况下,当您在服务管理器中查看服务的属性时,p4_1既是服务名称又是显示名称。您必须使用服务名称。
对于您的服务运营爱好者...请确保附加您的原因代码和注释!例如:'4'代表“计划内”的注释为“停止服务器进行维护”。
sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance

1
如果我需要使用另一个用户ID和密码登录,我该怎么做? - Frantumn
1
你可以通过运行 runas /user:Domain\UserName cmd 命令并输入密码,以其他用户/ID 的身份运行 CMD。CMD 将作为指定的用户帐户开始运行。 - user4317867

5
我们希望“net stop”命令可以停止服务。不幸的是,现实并不是那么简单明了。如果服务需要很长时间才能停止,命令将在服务停止之前返回。但是,除非您检查errorlevel,否则您将不知道这一点。
解决方案似乎是循环查找服务状态,直到其停止,并在每次循环时暂停一段时间。
但是...
我发现第一个服务需要很长时间才能停止,然后对于随后的服务,“net stop”命令似乎就无法起作用了。查看服务管理器中的服务,它的状态仍为“已启动”,没有变成“正在停止”。然而,我可以使用SCM手动停止第二个服务,它只需要3或4秒钟就能停止。

4

我刚刚使用了Jonas上面的例子,并创建了从0到24的所有错误级别列表。其他帖子正确指出:net startnet stop只使用errorlevel 0表示成功和2表示失败。

但这是对我有用的:

net stop postgresql-9.1
if %errorlevel% == 2 echo Access Denied - Could not stop service
if %errorlevel% == 0 echo Service stopped successfully
echo Errorlevel: %errorlevel%

stop更改为start并反向操作。


4

手动重启服务是可行的-在services.msc中有“重新启动”按钮,但是在命令行中,无论是sc命令还是net命令都没有“重启”开关,如果在cmd / bat文件中计划了重启,则服务会立即停止和启动,有时会出现错误,因为服务尚未停止,需要一些时间来关闭。

这可能会生成一个错误: sc stop sc start

最好插入超时时间,我使用ping(它每1秒钟ping一次): sc stop ping localhost -n 60 sc start


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接