从批处理脚本启动Windows服务,并根据结果采取适当的操作。
从批处理脚本启动Windows服务,并根据结果采取适当的操作。
我有一个.bat脚本,尝试在最后启动一个Windows服务。
:start_wildfly echo. set /p wildfly_service_name="输入Wildfly服务名称:" echo INFO: 正在启动 %wildfly_service_name%... echo. call net start "%wildfly_service_name%"
我希望能够解释net start
尝试的结果,以便如果失败时,我的脚本可以采取适当的操作(例如,如果服务已经运行,重新启动它。如果服务名称无效,则重新提示输入名称,如果用户权限不足,则退出)。
问题是NET命令不返回文档中的Win32_Service类代码。
然而,它会在控制台上显示错误信息:
The requested service has already been started.
More help is available by typing NET HELPMSG 2182.
请参阅http://ss64.com/nt/net_service.html以获取错误列表。
不幸的是,在这些错误情况下,errorlevel
变量始终为2
,所以我不能依赖它。
现在我正在尝试在NET
命令的输出上运行FIND
,搜索特定的错误代码并采取相应的操作。
net start Wildfly 2>&1 | FIND "2182" if %errorlevel% equ 0 goto service_already_running
因此,FIND
的结果存储在errorlevel
中,我可以通过检查errorlevel
是否为0来查看FIND
是否成功。这个方法有效。
现在的问题是,当我想检查多个错误代码时该怎么办。我不知道如何在上面的代码中扩展以检查是否还有"2185",并在那种情况下转到不同的标签。
我现在尝试将整个NET
命令的结果存储在一个变量中,然后在该变量上运行FINDSTR
。
setlocal EnableDelayedExpansion set "output_cnt=0" for /F "delims=" %%f in ('dir /b') do ( set /a output_cnt+=1 set "output[!output_cnt!]=%%f" ) for /L %%n in (1 1 !output_cnt!) DO echo !output[%%n]!
这应该存储和显示每行输出,然而最后一行似乎没有起作用。
然后我还找到了一些可以在变量中搜索并返回是否找到该字符串的代码:
echo.%output%|findstr /C:"2182" >nul 2>&1 && echo Found || echo Not found.
然而,我没有成功将它们结合起来。我只是想能够解释NET START
的结果,并根据结果跳转到特定的标签。
问题的出现的原因:
该脚本的目标是从批处理脚本中启动Windows服务,并根据结果采取相应的操作。脚本的目的是检查服务是否正在运行,如果是,则重新启动服务。然后,脚本再次检查服务是否已启动。如果服务未启动,则再次尝试启动。此外,脚本还添加了一段代码来处理权限不足的情况。
解决方法:
该脚本使用net start
命令来检查服务的状态,并根据结果采取相应的操作。首先,脚本会验证服务是否未运行。如果服务已经在运行,则脚本会重新启动服务。无论哪种情况,脚本都会在最后检查服务是否已经启动。如果未启动,则重复整个过程。此外,脚本还包含了一段代码来检查脚本是否以管理员权限运行,如果没有足够的权限,则显示错误消息并退出。
完整的脚本如下:
echo.
echo INFO: Starting %wildfly_service_name%...
echo.
:verify_not_running
net start | find "%wildfly_service_name%" > nul
if %errorlevel% equ 0 goto restart_wildfly
:start_wildfly
net start "%wildfly_service_name%"
goto verify_running
:restart_wildfly
echo The %wildfly_service_name% service is already running. Will now restart...
net stop "%wildfly_service_name%"
net start "%wildfly_service_name%"
:verify_running
net start | find "%wildfly_service_name%" > nul
if errorlevel 1 goto start_wildfly
:check_permissions
net session >nul 2>&1
if errorlevel 1 (
echo.
echo ERROR: This script must be run as an Administrator. Please re-run the script from an elevated command prompt.
echo.
echo Right-click "cmd.exe" from the Start menu and select "Run As Administrator".
exit /b %error_level%
)
这个脚本首先会验证服务是否未运行。如果服务已经在运行,则重新启动服务。无论哪种情况,脚本都会在最后检查服务是否已经启动。如果未启动,则重复整个过程。此外,脚本还包含了一段代码来检查脚本是否以管理员权限运行,如果没有足够的权限,则显示错误消息并退出。该脚本还假设服务名称已在脚本中硬编码。
问题出现的原因是在使用批处理脚本中的`net start`命令启动Windows服务时,无论出现何种错误,该命令都会返回2。然而,可以使用`sc start`命令作为`net start`的替代,而`sc start`命令会通过不同的退出状态指示不同的错误,特别是对于“服务实例已在运行”的错误,会返回退出状态1056。因此,可以使用以下代码来启动服务并在之后检查`%errorlevel%`的值来获取结果。
解决方法:
sc start "%wildfly_service_name%" if %errorlevel%==1056 ( echo An instance of the service is already running. REM 在此处添加适当的操作 ) else if %errorlevel%==0 ( echo The service has been started successfully. REM 在此处添加适当的操作 ) else ( echo Failed to start the service. REM 在此处添加适当的操作 )
这样,我们可以根据返回的退出状态来采取相应的操作,如输出相应的提示信息或执行其他相关操作。
问题的原因是希望能够根据net start
的结果来采取适当的操作,例如如果启动失败(例如服务已经在运行,则重新启动它。如果服务名称无效,则重新提示输入名称,如果用户没有足够的权限,则退出)。
解决方法如下:
首先,像之前一样启动服务:net start "%wildfly_service_name%"
。
然后检查服务的状态。有两种方法可以实现这个目的:
1.再次使用net start
来查看服务是否正在运行:net start | find "%wildfly_service_name%" > nul if errorlevel 1 echo The service is not running
。如果返回的errorlevel
为1,表示找不到服务。
2.使用sc
(Service Control)来检查服务状态:SC query %wildfly_service_name% | find "STATE" | find "STOPPED"
或者 sc query %wildfly_service_name% | find "STATE" | find "RUNNING"
。如果返回的errorlevel
为1,表示找不到相应的文本。
进一步阅读:
- Windows CMD命令行的A-Z索引 - 关于Windows命令行的详尽参考资料。
- net - 用于管理网络资源的NET命令。
- sc - 服务控制 - 创建、启动、停止、查询或删除任何Windows服务。
还有一种方法可以检测服务启动失败是否是由于权限不足引起的。可以使用net session >nul 2>&1
命令并检查errorlevel
的值。如果返回的errorlevel
为1,表示权限不足。
关于net start | find "servicename"
的工作原理,可以参考这里。建议添加不区分大小写的选项:net start | find /i "servicename"
。