批处理文件以在受监控文件夹中包含特定数量的文件时启动 .exe

moh*_*awk 2 windows-7 batch command-line batch-file

我正在尝试编写一个批处理文件,只要文件夹中有 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
Run Code Online (Sandbox Code Playgroud)

dbe*_*ham 5

我发现您的代码存在许多问题。但我看不出你是如何得到你所描述的行为的。

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

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

3) 你有一个额外的东西)可以提前关闭你的 IF 语句。在) ELSE ()线会被忽略,并在字里行间都无条件地执行。这是批处理解析器的一个奇怪的怪癖。如果解析器正在寻找一个命令,并且不存在一个左括号块,那么)该行后面的所有内容都将被忽略。

4) 如果您通过删除其中一行来修复括号),那么您仍然会遇到问题,因为您在复杂的 IF 语句中转到了一个标签。IF ELSE 语句被 GOTO 破坏,就像 FOR /F 语句一样。有关更多信息,请参阅/sf/ask/593709091/

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
Run Code Online (Sandbox Code Playgroud)

以上可以简化为:

@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
Run Code Online (Sandbox Code Playgroud)

但实际上,无论是否有 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
Run Code Online (Sandbox Code Playgroud)

由于第 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
Run Code Online (Sandbox Code Playgroud)

您的评论声称您在每次迭代中创建了所有 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
Run Code Online (Sandbox Code Playgroud)