如果超过一分钟的 Windows 批处理文件,则退出循环

Posted

技术标签:

【中文标题】如果超过一分钟的 Windows 批处理文件,则退出循环【英文标题】:Get out of loop if more than one minute Windows Batch file 【发布时间】:2021-01-20 14:13:23 【问题描述】:

如果满足特定条件,我正在尝试删除 Windows 服务器上的文件夹。如果不满足,则等待 10 秒并循环,再次检查条件。我还需要确保我不会永远处于循环中。 (检查我是否在循环中超过 60 秒,然后退出循环)。批处理文件如下所示:

C:\postgresql\uninstall-postgresql.exe --mode unattended
set TIMESTAMP1=%TIME%
:deleteFolder
tasklist /V |findstr /i "_uninstall*" >nul
if %errorlevel% == 0 (timeout /T /10 >nul
set TIMESTAMP2=%TIME%
**REM I want to make sure that we get out of this loop if the diff b/w TIMESTAMP2 
AND TIMESTAMP1 IS MORE THEN 60 SECONDS**
goto deleteFolder 
) ELSE (
if exists C:\postgresql RD /Q /S C:\postgresql)

Command 1
Command 2
Command 3

所以,我正在尝试从 Windows 服务器卸载 Postgresql,通过检查任务列表确保卸载完成,然后删除 basedir (C:\postgresql)。如果卸载过程仍在运行,则等待 10 秒并再次检查任务列表。我只是想确保我不会永远陷入困境。

提前致谢

【问题讨论】:

我很难理解如何或为什么,检查从tasklist 返回的errorlevel 通过findstr 将接近花费50 秒。尽管确保要查找的字符串是您想要的肯定也会有所帮助,但我可以设想字符串 _uninstall 存在,但不存在 _uninstalll_uninstallll 等。 如果您期望的是规范答案,则需要与所提出的问题匹配/配对,这是具体的而不是概括的。我还要说 cmets here、here 和 here 会以与您的期望相似的方式覆盖它。 @Compo -- 检查_uninstall 因为当你调用uninstall-postgres.exe 时,它​​每次都会以不同的名称执行uninstall.exe 进程。像_uninstall1833.exe 或_uninstall1699.exe 或类似的东西, 所以 findstr "_uninstall*" 所以你不需要"_uninstall*",因为*是一个通配符,表示另一个0或更多前一个字符。因此,我在之前的评论中告诉过你,(我非常怀疑你想匹配_uninstalll_uninstallll。你为什么不改用FindStr /IR "_uninstall[0123456789]*\.exe$?或者如果可执行文件以下划线开头,就像这样,FindStr /IR "^_uninstall[0123456789]*\.exe$ @Compo -- 听起来是个好主意...谢谢。 【参考方案1】:

使用时间戳和calculating time difference:

@echo off
setlocal EnableDelayedExpansion

C:\postgresql\uninstall-postgresql.exe --mode unattended

set "startTime=%time: =0%"
set "endTime="

:deleteFolder
tasklist /V |findstr /i "_uninstall*" >nul
if %errorlevel% == 0 (
    goto waitAndDeleteFolder
) else (
    goto cleanup
)

:waitAndDeleteFolder
timeout /T 10
set "endTime=%time: =0%"
set "end=!endTime:%time:~8,1%=%%100)*100+1!"  &  set "start=!startTime:%time:~8,1%=%%100)*100+1!"
set /A "elap=((((10!end:%time:~2,1%=%%100)*60+1!%%100)-((((10!start:%time:~2,1%=%%100)*60+1!%%100), elap-=(elap>>31)*24*60*60*100"
if !elap! gtr 6000 goto done
goto deleteFolder

:cleanup
if exist "C:\postgresql" RD /Q /S "C:\postgresql"
goto done

:done

【讨论】:

【参考方案2】:

更简单的方法是使用计数来打破循环

@Echo off & Set Count=0
 C:\postgresql\uninstall-postgresql.exe --mode unattended

:deleteFolder
If "%Count%"=="6" Goto :Failed
tasklist /V |%__AppDir_%findstr.exe /lic:"_uninstall" >nul 2> Nul && (Timeout /T 10 /Nobreak > Nul & <Nul Set /P "=." & Set /A "count+=1" & Goto :deleteFolder) || Goto :Post
:Post
if exist C:\postgresql (
 RD /Q /S C:\postgresql && Echo/Task Completed
) Else Echo/C:\postgresql Absent
Goto :Eof
:Failed
 Echo/Task failed to complete in the allocated time
Goto :Eof

不过,我建议您采用更稳健的方法来识别任务

【讨论】:

以上是关于如果超过一分钟的 Windows 批处理文件,则退出循环的主要内容,如果未能解决你的问题,请参考以下文章

如果文件在5分钟内增长超过一定大小,则发出警报

动态 WCF 客户端不会等待超过一分钟

在 Windows 任务计划程序中停止重复触发,直到第二天

日志监控文件中获取ip,每一分钟统计一次,超过200次的计入黑名单

windows调度程序每x分钟运行一次批处理脚本(.bat)? [复制]

一个表中有超过 3000 万个条目,执行一次选择计数需要 19 分钟