Я хочу сделать .bat файл, который удаляет временные файлы (запускается свернутый и закрывается автоматически) - PullRequest
0 голосов
/ 08 октября 2019

Я получил следующий код, который запускается свернутым, ждет 5 секунд (для медленного ПК), удаляет временные файлы после и должен автоматически закрываться, но по какой-то причине автоматическое закрытие не работает, файл .bat остается свернутым.

Я пытался использовать команду выхода, но у нее был 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

I 'Я с нетерпением жду исправления последнего шага автоматического закрытия, все остальные функции работают нормально, сценарий запускается свернутым, он удаляет временные файлы, но после всего этого он не закрывается и остается свернутым.

Ответы [ 3 ]

1 голос
/ 08 октября 2019

Причина, по которой ваш свернутый скрипт не закрывается в конце, заключается в том, что вы запустили скрипт напрямую, а не в качестве аргумента для 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

0 голосов
/ 08 октября 2019

Проблема в том, что первая строка не запускает явно 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

См. Также мой ответ на Как удалить файлы / подпапки в определенном каталоге из командной строки в Windows? Это объясняет, почему rd /Q /S "%~1" 2>nul достаточно для удаления всех подпапок и файлов в каталоге, путь которого передаетсяс аргументом 1 для подпрограммы Clear_Folder, если этот каталог действительно существует и pushd успешно сделал его текущим каталогом для командного процесса, обрабатывающего пакетный файл.

См. также: Где находится GOTO:EOF return to?

Что происходит после выполнения первого goto :EOF, зависит от того, как был запущен этот пакетный файл и в какой среде.

Двойной щелчок по пакетному файлу приводит кзапуск командного процессора Windows cmd.exe для обработки командного файла с использованием неявной опции /C to close comПроцесс мандата после выполнения командного файла. В этом случае первый goto :EOF приводит к закрытию первоначально открытого окна консоли, так как командный процесс Windows, обрабатывающий пакетный файл, первоначально также закрывается.

Первое открытие командной строки окна приводит к запуску cmd.exe с использованием неявной опции от /K до сохранить командный процесс, запущенный после выполнения командной строки, такой как выполнение этого пакетного файла. В этом случае окно консоли остается открытым после выполнения первого goto :EOF, поскольку командный процесс продолжает выполняться для дальнейшего выполнения команды пользователем.

Первый goto :EOF можно заменить командой exit, чтобы всегда exit командный процесс, не зависящий от того, как cmd.exe была начата первоначальная обработка командного файла, и не зависит от иерархии вызовов. Поэтому использование exit не рекомендуется, если этот пакетный файл вызывается из другого пакетного файла, который выполняет, например, больше операций очистки жесткого диска.

0 голосов
/ 08 октября 2019

Операторы 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 - это предопределенная метка, которая будет выходить из текущего скрипта или подпрограммы. Поэтому он пропустит что-либо в скрипте и просто прекратит выполнение дальнейших инструкций.

См. эту ссылку на ss64

...