0

I have come up with the following code which starts minimized, waits 5 seconds (for slow PC) deletes temp files after and should automatically close, but for some reason, automatic close is not working, .bat file stays minimized.

I tried using exit command but it has 0 effect because goto :EOF prevent it from execution, but if I will remove goto :EOF script won't delete temp files

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

I'm looking forward to fix last step auto close, all other features work fine, the script starts minimized, it deletes temp files but after all of this it won't close itself and it stays minimized.

Gerhard
  • 22,678
  • 7
  • 27
  • 43
laniakea
  • 81
  • 1
  • 11
  • I thought I'd mention that users can choose the location of their temporary file directory, so using specific paths is not the most robust idea. – Compo Oct 08 '19 at 09:02
  • I will also add that you should not delete all of the content of your temporary directories like this. I would suggest, _although it is now deprecated_, using the built-in Disk Cleanup, (`CleanMgr.exe`) instead. – Compo Oct 08 '19 at 10:52
  • 1
    Why don't you use variable [`%TEMP%`](https://ss64.com/nt/syntax-variables.html)? – aschipfl Oct 08 '19 at 12:12

3 Answers3

1

The reason your minimized script is not closing at the end is that you started the script directly, instead of as an argument to cmd.exe with it's /C option. When you run your script directly via Start, cmd.exe is run using the /K option with your batch file as its argument. When the /K option is used, as explained from running cmd /?, the window remains open upon completion of the command. To close that window you need to explicitly exit the cmd.exe instance:

Here's my take on what you intended to do:

@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

If there's no other content beneath this, you can also remove GoTo :EOF

Compo
  • 36,585
  • 5
  • 27
  • 39
0

The goto eof statements are explicitly going to end of file, skipping anything else, including your exit statement. You therefore need to change or remove it, in this instance I added a different label to goto which has only exit in the label. The second loop does not require the goto as it will fall through the label regardless:

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

To explain: goto :eof is a predefined label that will exit the current script or subroutine. It therefore will skip anything in the script and simply stops executing any further instructions.

See this link on ss64

Gerhard
  • 22,678
  • 7
  • 27
  • 43
0

The problem is the first line not explicitly starting cmd.exe with option /C to execute the batch file once again with a separate command process with minimized window.

@echo off
if defined IS_MINIMIZED goto ClearFolders
set "IS_MINIMIZED=1"
start "Clear Folders" /min %ComSpec% /C "%~f0" %*
exit /B

: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"
exit /B

:Clear_Folder
pushd "%~1"
if errorlevel 1 goto :EOF
rd /Q /S "%~1" 2>nul
popd
goto :EOF

See also my answer on How to delete files/subfolders in a specific directory at the command prompt in Windows? It explains why rd /Q /S "%~1" 2>nul is enough to delete all subfolders and files in directory of which path is passed with argument 1 to the subroutine Clear_Folder if that directory is really existing and pushd successfully made it the current directory for the command process processing the batch file.

See also: Where does GOTO :EOF return to?

What happens after execution of first exit /B depends on how this batch file was started and in which environment.

A double click on a batch file results in starting the Windows command processor cmd.exe for processing the batch file with using implicit option /C to close command process after execution of the batch file. In this case the first exit /B results in closing initially opened console window as the Windows command process processing the batch file initially also closes.

Opening first a command prompt window results in starting cmd.exe with using implicit option /K to keep command process running after execution of a command line like executing this batch file. In this case the console window remains open after execution of first exit /B as the command process keeps running for further command executions by the user.

The first exit /B could be replaced by command exit to always exit the command process independent on how cmd.exe initially processing the batch file was started and independent on the calling hierarchy. So the usage of exit is not advisable in case of this batch file is called from another batch file which does for example more hard disk cleanup operations.

Mofi
  • 46,139
  • 17
  • 80
  • 143