当受监视文件夹中的文件数量达到特定值时,启动 .exe 的批处理文件

当受监视文件夹中的文件数量达到特定值时,启动 .exe 的批处理文件

我正在尝试编写一个批处理文件,只要文件夹中正好有 4 张 jpg 图像,它就会触发一个 exe。之后应该删除这些图像。

看起来我已经让它工作了,但文件一遍又一遍地启动 exe。我似乎无法弄清楚错误是什么。

任何帮助是极大的赞赏!

@echo off
setlocal EnableDelayedExpansion
set counter=0

:loop
cd "c:\JPGfolder\"
for %%B in (*) do set /a counter+=1
echo File Count = !counter!

if !counter! EQU 4 (
for /f "delims=|" %%I in ('DIR "c:\JPGfolder\" /B /O:-D *.jpg') DO (
SET NewestFile=%%I
echo Newest File = "c:\JPGfolder\!NewestFile!"
start "" /w "c:\programs\generate.exe" "c:\JPGfolder\"%NewestFile%
del c:\JPGfolder\*.jpg
GOTO :BREAK
)
)

:BREAK
set /a counter=0

ping -n 2 localhost >nul

) else (
 echo No Files Found
 rem pause
 goto :loop
)
goto :loop

答案1

我发现你的代码有很多问题。但我不明白你是如何实现你所描述的行为的。

1) 您正在统计所有文件,但获取最新文件和删除所有文件的代码仅适用于 .jpg 文件。您的计数也应限制为 .jpg 文件。

2) 您忘记在 START 行中使用延迟扩展。但实际上,根本不需要使用环境值。您可以直接使用%%I,因此不需要延迟扩展。此外,整个文件路径应括在引号中。

3) 您有一个额外的)代码提前关闭了 IF 语句。) ELSE ()行会被忽略,而中间的行会无条件执行。 这是批处理解析器的一个奇怪特性。 如果解析器正在寻找命令,并且不存在打开的括号块,那么)该行上它之后的所有内容都会被忽略。

4) 如果您通过删除其中一行来修复括号),那么您仍然会遇到问题,因为您在复杂的 IF 语句中 GOTO 了一个标签。 IF ELSE 语句会被 GOTO 破坏,就像 FOR /F 语句一样。请参阅https://stackoverflow.com/q/8481558/1012053了解更多信息。

5) 您的 CD 语句应使用 /D 选项,以防万一您位于不同的卷上。或者使用 PUSHD。

6) 您的“未找到文件”消息不正确 - 它应该显示“文件数 <> 4”

7) 你的算法存在根本缺陷。如果你的代码第一次检查时有 3 个 .jpg 文件,而第二次检查时却有 5 个 .jpg 文件,那该怎么办?你的代码永远不会看到 4 个文件!

还有一些可能简化。

8) 由于您已将当前目录设置为“c:\JPGfolder”,因此您不再需要每次都明确指定文件的路径。您只需使用即可%%~fI获取完整路径。

9) 我将把计数的初始化移到:LOOP标签下方。这样您就不必担心在两个地方设置值。

我认为以下是您想要实现的逻辑。请记住,这不涉及第 7 点)。

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    ping -n 2 localhost >nul
    goto :break
  )
) else (
  echo File count <> 4
)
:break
goto :loop

以上内容可以简化为:

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    ping -n 2 localhost >nul
    goto :loop
  )
)
echo File count <> 4
goto :loop

但实际上,您可能应该在每次迭代中引入延迟,无论是否有 4 个 .jpg 文件。

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    goto :break
  )
) else (
  echo File count <> 4
)
:break
ping -n 2 localhost >nul
goto :loop

由于第 7 点,我不会使用上述任何代码。我无法解决这个问题,因为我不知道你的意图是什么。

更新

在我看来,您正在监视文件夹中的图像文件,并且想要按时间顺序用某个程序处理每 4 个文件。所有文件在收到后都会被删除。我建议移动文件而不是删除它们,以防万一出现问题并且您想要恢复其他图像。您随时可以手动删除已保存的文件。

您当前的算法要求批处理脚本读取和处理文件的速度比将图像添加到文件夹的速度更快,否则您可能会错过 4 个计数,并且不会再处理更多图像(我的第 7 点)。

下面是一种新算法,无论图像添加的速度有多快,它始终有效。

我没有在每次循环后将计数器重置为 0,而是让计数器无限增长。我使用模数算法来确定文件何时表示 4 的倍数(模数结果为 0)。我通过故意提高除以零的错误来检测模数 0 值,并||在出现错误时有条件地执行一段代码。

@echo off
setlocal
cd /d "c:\JPGfolder"
md save 2>nul
set counter=0

:LOOP
for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') do (
  set /a "1/((counter+=1)%%4)" 2>nul || (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
  )
    move "%%I" save >nul
)
ping -n 2 localhost >nul
goto :LOOP

您的评论声称您正在每次迭代中创建所有 4 幅图像的拼贴画。当您只将一个文件名传递给 generate.exe 时,我不明白这是如何工作的。但如果这确实是正在发生的事情,那么以下替代代码应该可以工作:

@echo off
setlocal
cd /d "c:\JPGfolder"
2>nul (
  md save
  md working
  del working\*
)
set counter=0

:LOOP
for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') do (
  move "%%I" working >nul
  set /a "1/((counter+=1)%%4)" 2>nul || (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~dpIworking\%%~nxI"
    move working\* save >nul
  )
)
ping -n 2 localhost >nul
goto :LOOP

答案2

您的逻辑是:如果计数器 = 4,则为文件夹中的每个 jpg 启动 exe。

在确定计数器等于 4 之后,在循环内将计数器设置为 0 并不会停止循环。

您还拥有一个不完整的 IF 语句,这是由一个多余的右括号(在 :BREAK 之前)造成的,它会干扰您的 ELSE 语句。

希望有帮助!

相关内容