【问题标题】:I want to make .bat file which deletes temps (starts minimized and closes automatically)我想制作删除临时文件的 .bat 文件(开始最小化并自动关闭)
【发布时间】:2023-12-31 04:01:01
【问题描述】:

我想出了以下代码,它开始最小化,等待 5 秒(对于慢速 PC)后删除临时文件并应自动关闭,但由于某种原因,自动关闭不起作用,.bat 文件保持最小化。

我尝试使用 exit 命令,但它的效果为 0,因为 goto :EOF 阻止它执行,但如果我将删除 goto :EOF 脚本不会删除临时文件

if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start "" /min "%~dpnx0" %* && exit
PING localhost -n 5 >NUL
@echo off
setlocal
call :Clear_Folder %SystemRoot%\TEMP
pushd C:\Users
for /d %%k in (*) do if exist "%%k\AppData\Local\Temp" call :Clear_Folder "%%k\AppData\Local\Temp"
popd
endlocal
goto :EOF
:Clear_Folder
pushd "%~1"
for /d %%i in (*) do rd /s /q "%%i"
del /f /q *
popd
goto :EOF
exit

我期待修复最后一步自动关闭,所有其他功能都可以正常工作,脚本开始最小化,它会删除临时文件,但在所有这些之后它不会自行关闭并保持最小化。

【问题讨论】:

  • 我想我会提到用户可以选择他们的临时文件目录的位置,所以使用特定路径并不是最可靠的想法。
  • 我还要补充一点,您不应该像这样删除临时目录的所有内容。我建议,虽然现在已弃用,但请改用内置的磁盘清理 (CleanMgr.exe)。
  • 为什么不使用变量%TEMP%

标签: batch-file minimize temp


【解决方案1】:

您的最小化脚本最后没有关闭的原因是您直接启动了脚本,而不是作为cmd.exe 的参数使用它的/C 选项。当您通过Start 直接运行脚本时,cmd.exe 将使用/K 选项运行,并将批处理文件作为其参数。当使用/K 选项时,正如运行cmd /? 所解释的那样,该窗口在命令完成后保持打开状态。要关闭该窗口,您需要明确地 exit cmd.exe 实例:

这是我对你打算做的事情的看法:

@If Not Defined IS_MINIMIZED Set "IS_MINIMIZED=1"&Start "" /Min "%~f0"&Exit
@Echo Off
Timeout 5 /NoBreak>NUL
Call :Clear_Folder "%SystemRoot%\TEMP"
For /D %%k In ("C:\Users\*")Do If Exist "%%k\AppData\Local\Temp\" Call :Clear_Folder "%%k\AppData\Local\Temp"
Exit
:Clear_Folder
PushD "%~1" 2>NUL||Exit /B
RD /S /Q "%~1" 2>NUL
PopD
GoTo :EOF

如果下面没有其他内容,也可以删除GoTo :EOF

【讨论】:

    【解决方案2】:

    goto eof 语句明确地转到文件末尾,跳过任何其他内容,包括您的 exit 语句。因此,您需要更改或删除它,在这种情况下,我向goto 添加了一个不同的标签,标签中只有exit。第二个循环不需要goto,因为无论如何它都会通过标签:

    if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start "" /min "%~dpnx0" %* && exit
    timeout 5>nul
    @echo off
    setlocal
    call :Clear_Folder %SystemRoot%\TEMP
    pushd C:\Users
    for /d %%k in (*) do if exist "%%k\AppData\Local\Temp" call :Clear_Folder "%%k\AppData\Local\Temp"
    popd
    endlocal
    exit
    :Clear_Folder
    pushd "%~1"
    for /d %%i in (*) do rd /s /q "%%i"
    del /f /q *
    popd
    

    解释一下:goto :eof 是一个预定义的标签,它将退出当前脚本或子程序。因此,它将跳过脚本中的任何内容,并停止执行任何进一步的指令。

    this link on ss64

    【讨论】:

      【解决方案3】:

      问题是第一行没有明确地以 cmd.exe 开头并带有选项 /C 以使用具有最小化窗口的单独命令进程再次执行批处理文件。

      @echo off
      if defined IS_MINIMIZED goto ClearFolders
      set "IS_MINIMIZED=1"
      start "Clear Folders" /min %ComSpec% /C "%~f0" %*
      goto :EOF
      
      :ClearFolders
      call :Clear_Folder "%SystemRoot%\TEMP"
      if defined TEMP call :Clear_Folder "%TEMP%"
      for /D %%k in (C:\Users\*) do if exist "%%k\AppData\Local\Temp" call :Clear_Folder "%%k\AppData\Local\Temp"
      goto :EOF
      
      :Clear_Folder
      pushd "%~1"
      if errorlevel 1 goto :EOF
      rd /Q /S "%~1" 2>nul
      popd
      goto :EOF
      

      另请参阅我在 How to delete files/subfolders in a specific directory at the command prompt in Windows? 上的回答它解释了为什么 rd /Q /S "%~1" 2>nul 足以删除目录中的 所有 子文件夹和文件,其中路径通过参数 1 传递给子例程 Clear_Folder 如果这样目录确实存在,pushd 成功地将其设置为处理批处理文件的命令进程的当前目录。

      另见:Where does GOTO :EOF return to?

      执行第一个goto :EOF 后会发生什么取决于此批处理文件的启动方式和环境。

      双击批处理文件会导致启动 Windows 命令处理器 cmd.exe 以处理批处理文件,并在执行批处理文件后使用隐式选项 /C关闭命令进程。在这种情况下,第一个 goto :EOF 会导致关闭最初打开的控制台窗口,因为最初处理批处理文件的 Windows 命令进程也会关闭。

      首先打开command prompt 窗口会导致使用隐式选项/K 启动cmd.exe,以保持命令进程在执行命令行(如执行此批处理文件)后继续运行。在这种情况下,控制台窗口在执行第一个 goto :EOF 后保持打开状态,因为命令进程会继续运行以供用户进一步执行命令。

      第一个goto :EOF 可以替换为命令exit,以始终退出命令进程,而与cmd.exe 最初处理批处理文件的方式无关,并且与调用层次结构无关。因此,如果该批处理文件是从另一个批处理文件中调用的,例如执行更多的硬盘清理操作,则不建议使用exit

      【讨论】: