使用 for 循环等待进程在远程 PC 上终止

Waiting for Process to terminate on a remote PC using for loop

应该可以解决这个问题,但我在兜圈子。我知道这与 setlocal 有关 EnableDelayedExpansion,但我遗漏了一些东西。

目标: 在远程机器上执行 windows (cleanmgr.exe) 脚本,等到 Cleanmgr.exe 关闭然后 启动脚本从远程“键入”结果日志文件(通过清理脚本生成) 系统在CMD window.

工作原理: 远程机器上的脚本 运行 运行良好,它将 C: free drive space 回显到日志文件中, 然后清理 PC,然后重新运行磁盘 space 报告并将结果回显到同一个日志文件中, 因此用户可以通过之前和之后的结果看到(/有 t运行sparency of)回收的 space。

什么坏了: 在目标 PC 上检查 Cleanmgr.exe 的 WMIC 命令仅在等待重试时起作用一次 包含主机名的变量已被清除。我可以通过回显来看到行为 变回.

修复尝试: 我有一种预感,这与一旦 if 语句在 运行 中丢失的变量有关 括弧。我尝试了很多选项,但它们的行为都一样。我试过跳 使用 %1 而不是 %%i 处理以在原始代码外循环,但就是不能完全到达那里。

感谢任何改进。

@echo off
pushd %~dp0
color 1e
setlocal EnableDelayedExpansion
title HDD Space Checker...
for /f %%i in (hostnames.txt) do (
xcopy /y cleanupwindows-sfd.bat \%%i\C$\IT
WMIC /node:"%%i" process call create "C:\IT\cleanupwindows-sfd.bat"
echo Waiting For Processes...
timeout -t 10 /nobreak >nul
:loop
WMIC /node:"%%i" process where name="cleanmgr.exe" get name |find "cleanmgr.exe">nul
IF "!errorlevel!"=="0" set running=var
IF "!running!"=="var" timeout -t 4 >nul & echo Still Running & goto :loop
IF "!running!"=="" timeout -t 4 >nul & type \%%i\C$\IT\%%i_HHD_Space.log
)
pause
exit

至少要看两点

  1. 您的 running 变量一旦设置,就永远不会重置,从而触发无限循环
  2. 您在括号内的 goto 语句驱动命令解释器 (cmd.exe) 停止评估块,因此您的脚本松开 %%i 并离开 for 循环,因此当终止 :loop 循环时,您的脚本将离开 for 循环而不循环到 hostnames.txt.
  3. 中的其他值

为了解决这个问题,将您的流程代码放在一个用 CALL 调用的子例程中,并在每个 :loop 周期重置 running 变量:

@echo off
pushd %~dp0
color 1e
setlocal EnableDelayedExpansion
title HDD Space Checker...
for /f %%i in (hostnames.txt) do (
  CALL:Process "%%i"
)
pause
exit
:Process
xcopy /y cleanupwindows-sfd.bat \%~1\C$\IT
WMIC /node:"%~1" process call create "C:\IT\cleanupwindows-sfd.bat"
echo Waiting For Processes...
timeout -t 10 /nobreak >nul
:loop
set "running="
WMIC /node:"%~1" process where name="cleanmgr.exe" get name |find "cleanmgr.exe">nul
IF "!errorlevel!"=="0" set "running=var"
IF "!running!"=="var" timeout -t 4 >nul & echo Still Running & goto :loop
IF "!running!"=="" timeout -t 4 >nul & type \%~1\C$\IT\%~1_HHD_Space.log
GOTO:EOF

说明:CALL 语句意味着命令解释器将在执行关联的 subprocess/command/etc.. 当 subprocess/command/etc 时存储当前执行的脚本行及其状态。 . 完成后,命令解释器继续执行脚本到具有恢复上下文的下一行。这避免了 for 循环上下文的松动。