如果您想在一个循环中使用 FOR 批量执行此操作:
FOR /F "tokens=2,3 delims=: " %%H IN ('^(SC QUERY "Service1" ^& SC QUERY "Service2"^) ^| FINDSTR /C:"SERVICE_NAME" /C:" STATE" ') DO (IF NOT "%%H" == "" (IF "%%I" == "" SET LOCALV_SERV=%%H) & IF NOT "%%I" == "" (IF /I "%%I" NEQ "RUNNING" CALL NET START %%LOCALV_SERV%%))
我们通过连接多个 SC 输出一次查询多个服务,然后在这里使用 FINDSTR 功能一次搜索多个字符串以获得服务名称和服务状态。
按照@Compo 的建议,您应该测试许多其他服务状态。
那么对于您的用例,命令应该是:
FOR /F "tokens=2,3 delims=: " %%H IN ('^(SC QUERY "Service1" ^& SC QUERY "Service2" ^& SC QUERY "Service3" ^& SC QUERY "Service4" ^& SC QUERY "Service5"^) ^| FINDSTR /C:"SERVICE_NAME" /C:" STATE" ') DO (IF NOT "%%H" == "" (IF "%%I" == "" SET LOCALV_SERV=%%H) & IF NOT "%%I" == "" (IF /I "%%I" NEQ "RUNNING" CALL NET START %%LOCALV_SERV%%))
将 Service1、Service2、Service3、Service4、Service5 替换为您要定位的服务名称。
由于@Compo 指出使用 CALL 进行延迟扩展可能不合适,因此这里是显式启用延迟扩展的相同脚本:
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=2,3 delims=: " %%H IN ('^(SC QUERY "Service1" ^& SC QUERY "Service2"^) ^| FINDSTR /C:"SERVICE_NAME" /C:" STATE" ') DO (IF NOT "%%H" == "" (IF "%%I" == "" SET LOCALV_SERV=%%H) & IF NOT "%%I" == "" (IF /I "%%I" NEQ "RUNNING" NET START !LOCALV_SERV!))
这是我的答案的扩展,基于 cmets,它仅在循环内需要的地方启用延迟扩展。这个版本还去掉了对%PATH%、%PATHEXT%的依赖,提高了可读性:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "SC=%SystemRoot%\System32\sc.exe"
Set "FS=%SystemRoot%\System32\findstr.exe"
For /F "Tokens=2-3 Delims=: " %%G In ('
(%SC% Query "Service1" ^&
%SC% Query "Service2" ^&
%SC% Query "Service3" ^&
%SC% Query "Service4" ^&
%SC% Query "Service5"^) 2^>NUL
^| %FS% /BIC:"SERVICE_NAME:" /C:" STATE "
') DO (
If Not "%%G" == "" If "%%H" == "" Set "LOCALV_SERV=%%G"
If Not "%%H" == "" If /I Not "%%H" == "RUNNING" (
SetLocal EnableDelayedExpansion
%SC% Start !LOCALV_SERV!
EndLocal
)
)