Batch file 已达到最大setlocal递归级别&;endlocal。解决办法?

Batch file 已达到最大setlocal递归级别&;endlocal。解决办法?,batch-file,recursion,cmd,batch-processing,command-prompt,Batch File,Recursion,Cmd,Batch Processing,Command Prompt,我有一段代码正在执行0-100000次。出现问题的块如下所示: FOR /R %%f IN (*.*) DO ( CLS ECHO Del 2.0 ECHO Files Done^: !FILES_DONE! / !FILES_TOTAL! ECHO Missing^: !FILES_MISSING! SETLOCAL DisableDelayedExpansion SET "FILES_TEMP=%%f" SETLOCAL EnableDelayedExpansio

我有一段代码正在执行0-100000次。出现问题的块如下所示:

FOR /R %%f IN (*.*) DO (
  CLS
  ECHO Del 2.0
  ECHO Files Done^: !FILES_DONE! / !FILES_TOTAL!
  ECHO Missing^: !FILES_MISSING!
  SETLOCAL DisableDelayedExpansion
  SET "FILES_TEMP=%%f"
  SETLOCAL EnableDelayedExpansion
  IF EXIST "!FILES_TEMP!" (
    !DELITE! -p 13 -q "!FILES_TEMP!" >NUL
    SET /A FILES_DONE += 1
  ) ELSE (
    SET /A FILES_MISSING += 1
  )
)
在此块中:
!文件完成了
!文件总数,和
!文件不见了都是整数变量

!德利特是对可执行文件的引用:“!CD!\\u sdelete.exe”其中“!CD!”是执行批处理的根文件夹

注意:请注意,打开/关闭DelayedExpansion是必要的,因为我需要捕获可能有或可能没有特殊字符的文件名,例如:“!”和“^”

所以我的问题是:如何重新格式化这段代码,以避免抛出达到的最大递归级别错误?(我知道这个问题经常被问到,而这只是我问题的一半,所以请容忍我)

第二,有人能解释一下这段代码在本地环境中的作用吗

SETLOCAL EnableDelayedExpansion
FOR /R %%f IN (*.*) DO (
  ECHO !FILES_DONE! / !FILES_TOTAL!
  ENDLOCAL & (
    SET "FILES_TEMP=%%f"
  )
  [etc...]
)
例如,一旦它在代码中循环一次,“endlocal”是否仍然有效,还是因为它是一个新循环而被恢复?此外,它是否有助于达到最大Setlocal水平

来自码码码码码码码码码码码码码方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方本35现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场#############

Del 2.0-为任何想要使用它的人提供完整的文件内容
注意:如果有人想要Del批处理的更新副本,请给我发消息;它目前在V3.0-R0上,您需要使用。我可能会在一个网站上作为一个免费的扩展,为任何想要一个安全删除程序的人托管这个

@ECHO OFF
SETLOCAL EnableDelayedExpansion
TITLE Del 2.0
GOTO PRECHECK

:PRECHECK
ECHO Del 2.0
ECHO Checking...
IF NOT EXIST "!CD!\To-Do" (
  ECHO To-Do Folder Not Found
  ECHO.
  ECHO Nothing To Delete
  PAUSE >NUL
  GOTO END
)
IF NOT EXIST "!CD!\_sdelete.exe" (
  ECHO SDelete Program Not Found
  ECHO.
  ECHO Core File "_sdelete.exe" Missing
  PAUSE >NUL
  GOTO END
) ELSE (
  ATTRIB +S +H "!CD!\_sdelete.exe" >NUL
)
TIMEOUT /T 1 /NOBREAK >NUL
GOTO SETVARS

:SETVARS
CLS
ECHO Del 2.0
ECHO Writing Variables...
SET TAB=    
SET FILES_TEMP=0
SET FILES_TOTAL=0
SET FILES_DONE=0
SET FILES_MISSING=0
SET ROOTCD=!CD!
SET HOMECD=!CD!\To-Do
SET DELITE="!CD!\_sdelete.exe"
TIMEOUT /T 1 /NOBREAK >NUL
GOTO START

:START
CLS
ECHO Del 2.0
ECHO Starting...
ATTRIB -S -H ** /S /D
CD To-Do
TIMEOUT /T 1 /NOBREAK >NUL
CLS
ECHO Del 2.0
ECHO Counting Files...
FOR /R %%f IN (**) DO (
  CLS
  SET /A FILES_TOTAL += 1
  ECHO Del 2.0
  ECHO Files Found^: !FILES_TOTAL!
)
TIMEOUT /T 1 /NOBREAK >NUL
GOTO ERASEFILES

:ERASEFILES
CLS
ECHO Del 2.0
ECHO Erasing Files...
SETLOCAL DisableDelayedExpansion
FOR /R %%f IN (*.*) DO (
  SET "FILES_TEMP=%%f"
  CALL :SUBERASE
)
GOTO FINISHERASE

:SUBERASE
CLS
ECHO Del 2.0
ECHO Files Done^: %FILES_DONE% / %FILES_TOTAL%
ECHO Missing^: %FILES_MISSING%
IF EXIST "%FILES_TEMP%" (
  %DELITE% -p 13 -q "%FILES_TEMP%" >NUL
  SET /A FILES_DONE += 1
) ELSE (
  SET /A FILES_MISSING += 1
)
EXIT /B

:FINISHERASE
SETLOCAL EnableDelayedExpansion
CLS
ECHO Del 2.0
ECHO Files Done^: !FILES_DONE! / !FILES_TOTAL!
ECHO Missing^: !FILES_MISSING!
TIMEOUT /T 3 /NOBREAK >NUL
GOTO CLEANUP

:CLEANUP
CLS
ECHO Del 2.0
ECHO Cleaning Up...
IF !FILES_MISSING! EQU 0 (
  FOR /D %%f in (*.*) DO (
    SETLOCAL DisableDelayedExpansion
    SET "FILES_TEMP=%%f"
    SETLOCAL EnableDelayedExpansion
    RD "!FILES_TEMP!" /S /Q >NUL
  )
)
TIMEOUT /T 1 /NOBREAK >NUL
GOTO END

:END
CLS
ECHO Del 2.0
ECHO Complete^^!
TIMEOUT /T 3 /NOBREAK >NUL
EXIT
使用以下方法保持禁用状态:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
FOR /R %%f IN (*.*) DO (
  SET "FILES_TEMP=%%f"
  CALL :doAll
)
goto :skipSubroutine

:doAll
  CLS
  ECHO Del 2.0
  ECHO Files Done^: %FILES_DONE% / %FILES_TOTAL%
  ECHO Missing^: %FILES_MISSING%
  IF EXIST "%FILES_TEMP%" (
    %DELITE% -p 13 -q "%FILES_TEMP%" >NUL
    SET /A FILES_DONE += 1
  ) ELSE (
    SET /A FILES_MISSING += 1
  )
goto :eof

:skipSubroutine
如果
FILES\u TEMP
变量需要,则
:doAll
子例程可以如下所示(请注意,
ENDLOCAL
命令用于两次在脚本范围内正确更新变量
FILES\u DONE
FILES\u MISSING
):


谢谢,我会立即测试它,并接受它,如果它证明工作顺利。当“:release”包含“exit/b”时,我可以使用“goto:release”,而不是使用“goto:eof”,对吗?“exit”将终止脚本,而“exit/b”将终止调用?对不起,这是一个很基本的问题,我对这个问题很不熟悉CALL@JoeBro请阅读-
goto中的EOF段落:如果启用,EOF
exit/B
是等效的。为了安全起见,请不要在脚本中的任何位置声明
:eof
标签。它工作得非常好!我编辑了提供的代码,以便与脚本的其余部分一起“玩得很好”;但谢谢你,我会接受这个作为答案,只要我有其他子问题的答案;但这解决了大部分问题。至少有人能投我一票吗?是的,我记得:eof实际上表示文件的结尾,而不是实际的标签;感谢您告诉我它们是等效的,这是非常有用的信息。现在唯一的“缺少”/“跳过”文件(我添加了该功能以使使用“!”和“^”调试文件更容易)只是由于目录名太长,这是合理的、可管理的,而且非常少见。再次感谢你!它确实工作得很好。
:doAll
  CLS
  ECHO Del 2.0
  ECHO Files Done^: %FILES_DONE% / %FILES_TOTAL%
  ECHO Missing^: %FILES_MISSING%
  SETLOCAL EnableDelayedExpansion
  IF EXIST "!FILES_TEMP!" (
    %DELITE% -p 13 -q "!FILES_TEMP!" >NUL
    ENDLOCAL
    SET /A FILES_DONE += 1
  ) ELSE (
    ENDLOCAL
    SET /A FILES_MISSING += 1
  )
goto :eof