如何编写 bat 或 cmd 脚本以通过错误检查可靠地停止和启动服务(或让我知道无论出于何种原因它都没有成功)?
使用 SC
(服务控制)命令,它为您提供了比 start
& 更多的选项stop
。
DESCRIPTION: SC is a command line program used for communicating with the NT Service Controller and services. USAGE: sc <server> [command] [service name] ... The option <server> has the form "\\ServerName" Further help on commands can be obtained by typing: "sc [command]" Commands: query-----------Queries the status for a service, or enumerates the status for types of services. queryex---------Queries the extended status for a service, or enumerates the status for types of services. start-----------Starts a service. pause-----------Sends a PAUSE control request to a service. interrogate-----Sends an INTERROGATE control request to a service. continue--------Sends a CONTINUE control request to a service. stop------------Sends a STOP request to a service. config----------Changes the configuration of a service (persistant). description-----Changes the description of a service. failure---------Changes the actions taken by a service upon failure. qc--------------Queries the configuration information for a service. qdescription----Queries the description for a service. qfailure--------Queries the actions taken by a service upon failure. delete----------Deletes a service (from the registry). create----------Creates a service. (adds it to the registry). control---------Sends a control to a service. sdshow----------Displays a service's security descriptor. sdset-----------Sets a service's security descriptor. GetDisplayName--Gets the DisplayName for a service. GetKeyName------Gets the ServiceKeyName for a service. EnumDepend------Enumerates Service Dependencies. The following commands don't require a service name: sc <server> <command> <option> boot------------(ok | bad) Indicates whether the last boot should be saved as the last-known-good boot configuration Lock------------Locks the Service Database QueryLock-------Queries the LockStatus for the SCManager Database EXAMPLE: sc start MyService
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 表示成功。任何更高的值都表示失败。
作为 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
编辑 20.04.2015
返回代码:
NET 命令不返回记录在案的 Win32_Service 类返回代码(服务未激活、服务请求超时等),并且对于许多错误只会返回错误级别 2。
看这里:http://ss64.com/nt/net_service.html
NET
不 仅用于服务相关功能,而 SC
仅用于服务相关功能。
errorlevel
是 2,see here how to interpret the error result。
您可以使用 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%
免责声明:我是从头顶写的,但我认为它会起作用。
而不是检查代码,这也有效
net start "Apache tomcat" || goto ExitError
:End
exit 0
:ExitError
echo An error has occurred while starting the tomcat services
exit 1
我为此创建了我的个人批处理文件,我的有点不同,但可以随意修改。我不久前创建了这个,因为我很无聊,想为人们提供一种简单的方法来输入结束、开始、停止或设置为自动。此 BAT 文件仅要求您输入服务名称,其余的工作将由您完成。我没有意识到他正在寻找说明任何错误的东西,我一定是误读了那部分。虽然通常这可以通过在行尾输入 >> output.txt 来完成。
%var% 只是用户能够将自己的服务输入其中的一种方式,而不必每次要启动/停止不同的服务时都去修改 bat 文件。
如果我错了,任何人都可以随时纠正我。
@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
语法总是让我......所以......
如果您是两台机器上的管理员,以管理员身份运行 .bat 并且机器位于同一域中,那么这里明确地如何向批处理文件添加一行,该行将终止远程服务(在另一台机器上)。机器名称遵循 UNC 格式 \myserver
sc \\ip.ip.ip.ip stop p4_1
在这种情况下... p4_1 既是服务名称又是显示名称,当您在服务管理器中查看服务的属性时。您必须使用服务名称。
对于您的 Service Ops 迷……请务必附加您的原因代码和评论!即“4”等于“已计划”并注释“停止服务器进行维护”
sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance
runas /user:Domain\UserName cmd
以其他用户/ID 的身份运行 CMD
,然后输入您的密码。 CMD 将以指定的用户帐户开始运行。
我们想认为“net stop”会停止服务。可悲的是,现实并非非黑即白。如果服务需要很长时间才能停止,该命令将在服务停止之前返回。但是,除非您检查错误级别,否则您不会知道。
解决方案似乎是循环查找服务的状态,直到它停止,每次循环都暂停。
但话又说回来...
我看到第一个服务需要很长时间才能停止,然后后续服务的“网络停止”似乎什么都不做。查看服务管理器中的服务,它的状态仍然是“已启动”——没有更改为“正在停止”。然而,我可以使用 SCM 手动停止第二个服务,它会在 3 或 4 秒内停止。
或者您可以使用此 cmd 启动远程服务:sc \\<computer> start <service>
我刚刚使用了上面 Jonas 的示例并创建了 0 到 24 个错误级别的完整列表。其他帖子是正确的,net start
和 net 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
并反过来工作。
手动重启服务没问题 - services.msc 有“重启”按钮,但在命令行中,sc 和 net 命令都缺少“重启”开关,如果在 cmd/bat 文件中安排重启,服务会立即停止并启动,有时会收到错误,因为服务尚未停止,需要一些时间才能关闭。
这可能会产生错误:sc stop sc start
插入超时是个好主意,我使用 ping(它每 1 秒 ping 一次): sc stop ping localhost -n 60 sc start
这是使用批处理启动系统还原的 Windows 10 命令:
sc config swprv start= Auto
您可能还喜欢这些命令:
将注册表值更改为自动启动系统还原 REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" /v DisableSR /t REG_DWORD /d 0 /f
创建系统还原点 Wmic.exe /Namespace:\root\default Path SystemRestore Call CreateRestorePoint "djibe saved your PC", 100, 12
Change System Restore disk usage vssadmin resize shadowstorage /for=C: /on=C: /maxsize=10%
享受
SC
可以使用服务完成所有操作...启动、停止、检查、配置等等...
有时你会发现停止不起作用..
我的 SQlServer 有时会这样做。使用以下命令行会杀死它。如果你真的需要你的脚本来杀死那些不会停止的东西。我会把它作为最后的手段
taskkill /pid [pid number] /f
SC NET STOP/START PsService WMIC Powershell 也是易于使用的选项
SC 和 NET 已经作为 anwests 给出。 PsService 添加了一些简洁的功能,但需要从 Microsoft 下载。
但我最喜欢的方式是使用 WMIC,因为 WQL 语法提供了一种强大的方式来管理多个服务(也可以通过 powershell/vbscript/jscript/c# 使用 WMI 对象)。
最简单的使用方法:
wmic service MyService call StartService
wmic service MyService call StopService
并以 WQL 为例
wmic service where "name like '%%32Time%%' and ErrorControl='Normal'" call StartService
这将启动名称包含 32Time
并具有正常错误控制的所有服务。
Here 是您可以使用的方法。
和 :
wmic service get /FORMAT:VALUE
您可以查看有关服务的可用信息。
我正在用 C# 编写 Windows 服务,停止/卸载/构建/安装/启动循环太累了。编写了一个迷你脚本,将其命名为 reploy.bat
并放入我的 Visual Studio 输出目录(具有构建的服务可执行文件的目录)以自动执行循环。
只需设置这 3 个变量
servicename
:这显示在 Windows 服务控制面板 (services.msc)
slndir
:包含您的解决方案 (.sln) 文件的文件夹(不是完整路径)
binpath
:从构建到服务可执行文件的完整路径(不是文件夹路径)
注意:这需要从 Visual Studio 开发人员命令行运行 msbuild
命令才能工作。
SET servicename="My Amazing Service"
SET slndir="C:dir\that\contains\sln\file"
SET binpath="C:path\to\service.exe"
SET currdir=%cd%
call net stop %servicename%
call sc delete %servicename%
cd %slndir%
call msbuild
cd %bindir%
call sc create %servicename% binpath=%binpath%
call net start %servicename%
cd %currdir%
也许这对某人有帮助:)
我没有找到上述任何答案来提供令人满意的解决方案,因此我编写了以下批处理脚本...
:loop
net stop tomcat8
sc query tomcat8 | find "STOPPED"
if errorlevel 1 (
timeout 1
goto loop
)
:loop2
net start tomcat8
sc query tomcat8 | find "RUNNING"
if errorlevel 1 (
timeout 1
goto loop2
)
它一直运行net stop,直到服务状态为STOPPED,只有在状态停止后才运行net start。如果服务需要很长时间才能停止,net stop 可能会失败终止。如果由于某种原因服务没有成功启动,它将继续尝试启动服务,直到状态为 RUNNING。
有了这个可以启动需要服务的服务或程序
@echo
taskkill /im service.exe /f
taskkill /im service.exe /f
set "reply=y"
set /p "reply=Restart service? [y|n]: "
if /i not "%reply%" == "y" goto :eof
cd "C:\Users\user\Desktop"
start service.lnk
sc start service
eof
exit