批处理文件未在循环中处理变量

批处理文件未在循环中处理变量

我一直在努力改进这个批处理文件。我的目标是让它停止列表中的第一个服务并等到它完全停止,或者如果它不能快速停止就将其终止,然后重新启动它,并等到服务完全启动后再停止列表中的下一个服务。

如本例所示,它首先将每个服务的名称写入文件,然后读取它们。它应该将它们放在 %%a 字段中,但它却将 Service_%a 作为服务名称放入其中,然后失败。

我该如何改变它才能让它读取正确的名称?

@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO ---------------------------------------------->> log.txt
ECHO -----------========================----------->> log.txt
ECHO -----------=========%date%=========----------->> log.txt
ECHO -----------========================----------->> log.txt
ECHO ---------------------------------------------->> log.txt

set DD=0
Set TIMESTAMP="eol=; tokens=1,2,3,4* delims=/, "
For /F %TIMESTAMP% %%i in ('DATE /t') DO (
  SET YYYYMMDD=%%l%%j%%k
  SET YYYYMM=%%l%%j
  set DD=%%k
)

echo 3050 >> services
echo 3051 >> services
echo 3052 >> services

for /f %%a in (services) do (
  set timestamp=!date!!time!
  ECHO !timestamp! - Stopping Service %%a >> log.txt
  sc stop Service_%%a >> log.txt
  timeout /t 15 > NUL
  for /f "tokens=4" %%s in ('sc query "Service_%%a" ^| find "STATE"') do if NOT "%%s"=="STOPPED" goto ForceStop
  goto Start

  :ForceStop
  ECHO !timestamp! - Service could not be stopped, forcing... >> log.txt
  taskkill /f /im Service_%%a.exe >> log.txt

  :Start
  ECHO !timestamp! - Service is stopped >> log.txt

  timeout /t 5 > NUL

  set timestamp=!date!!time!
  ECHO !timestamp! - Starting Service %%a >> log.txt
  sc start "Service_%%a" >> log.txt

  :WAIT
  ECHO !timestamp! - Service not yet started >> log.txt
  timeout /t 5 > NUL
  for /f "tokens=4" %%s in ('sc query "Service_%%a" ^| find "STATE"') do if NOT "%%s"=="RUNNING" goto WAIT
  ECHO !timestamp! - Service is started >> log.txt  
)
if exist services del services

答案1

echo 3050 >> services
         ^              remove this evil space

因为虽然sc query "Service_3050"可以工作,sc query "Service_3050 "但是额外的空间会引发下一个错误:

[SC] EnumQueryServicesStatus:OpenService FAILED 1060:

The specified service does not exist as an installed service.

还有另一种严重代码错误:使用:label 里面(括号内的代码块将)破坏for循环上下文。请call :label按如下方式使用:

for /f %%a in (services) do (
  set timestamp=!date!!time!
  ECHO !timestamp! - Stopping Service %%a >> log.txt
  sc stop Service_%%a >> log.txt
  timeout /t 15 > NUL
  for /f "tokens=4" %%s in ('
        sc query "Service_%%a" ^| find "STATE"
        ') do if NOT "%%s"=="STOPPED" CALL :ForceStop "%%a%

  ECHO !timestamp! - Service is stopped >> log.txt

  timeout /t 5 > NUL

  set timestamp=!date!!time!
  ECHO !timestamp! - Starting Service %%a >> log.txt
  sc start "Service_%%a" >> log.txt

    call :WAIT "%%a%
)
goto :done

:WAIT
ECHO !timestamp! - Service not yet started >> log.txt
timeout /t 5 > NUL
for /f "tokens=4" %%s in ('
    sc query "Service_%~1" ^| find "STATE"
    ') do if NOT "%%s"=="RUNNING" goto :WAIT
ECHO !timestamp! - Service is started >> log.txt  
exit /B

:ForceStop
ECHO !timestamp! - Service could not be stopped, forcing... >> log.txt
taskkill /f /im Service_%~1.exe >> log.txt
exit /B

:done
if exist services del services

资源(必读):

相关内容