Пакетный скрипт удаляет сам себя
-
10-07-2019 - |
Вопрос
У меня есть .bat
скрипт, запускающий java
программа.Тот самый java
программа удаляет папку, в которой находится .bat
садится.У меня нет возможности прикоснуться к java
программа.Я могу только изменить .bat
файл.
Проблема в том, что .bat
файл, после удаления, сразу же останавливает свое выполнение, не завершая его.Но есть некоторые задачи по очистке, которые необходимо выполнить после java
программа завершается.
Я попытался скопировать .bat
запишите файл в другое место и запустите его в таком месте, где он не будет удален.Увы, когда-то оригинал .bat
удаляется, потому что он все еще находится в процессе выполнения, происходит тот же сбой, и он не завершается.
Вот два примера файлов (для целей примера давайте представим, что они расположены в D:\tmp
) :
удалить.bat
echo "delete start"
pause
del launch.bat
pause
echo "delete end"
запуск.bat
echo "launch start"
setlocal enabledelayedexpansion enableextensions
if "%CD%"=="C:\tmp" (
echo "in temp"
d:
cd \tmp
delete.bat
)
if "%CD%" NEQ "C:\tmp" (
echo "not in temp"
mkdir C:\tmp
copy launch.bat C:\tmp\launch.bat
echo "launch copied"
C:
cd \tmp
cmd /c launch.bat
)
echo "launch end"
Запуск launch.bat
сработало бы, если бы выполнение скопированного launch.bat
были отделены от первоначального.
Кто-нибудь знает способ сделать .bat
завершить его выполнение, даже если он будет удален во время выполнения?
Решение 4
Кажется, я добился лучшего результата, сделав это следующим образом (вызывая launch.bat
с cmd /k
) :
запуск.bat
echo "launch start"
setlocal enabledelayedexpansion enableextensions
if "%CD%"=="C:\tmp" (
echo "in temp"
d:
cd \tmp
delete.bat
echo "after delete"
)
if "%CD%" NEQ "C:\tmp" (
echo "not in temp"
mkdir C:\tmp
copy launch.bat C:\tmp\launch.bat
echo "launch copied"
C:
cd \tmp
cmd /k launch.bat
)
echo "launch end"
Теперь я могу дотянуться до echo "after delete"
, но я каким-то образом оказываюсь в бесконечном цикле.По крайней мере, моя очистка может быть выполнена на этом этапе.Не знаю, почему я не могу дотянуться echo "launch end"
, хотя.
Другие советы
Это даст команду скрипту удалить себя, а затем завершить работу.Интерпретатор команд считывает всю строку до того, как строка будет выполнена, поэтому команда exit будет выполнена после команды delete, даже если файл больше не существует.
del /f/q "%~0" | exit
В качестве альтернативы, вы можете использовать круглые скобки, если хотите выполнить много команд после удаления файла, поскольку интерпретатор команд прочитает все, что находится внутри круглых скобок, прежде чем выполнить его.
(del /f/q "%~0"
if exist "%~0" (echo.How did that happen?) else (echo.I've deleted myself.)
pause
exit)
Кто -нибудь знает способ заставить файл .bat завершить свое выполнение, даже если он будет удален во время выполнения?
Я не думаю, что это возможно.Пакетное выполнение считывается непосредственно из файла.Если вы измените файл, это изменит выполнение (самоизменяющиеся пакетные программы удивительно сложно отлаживать!)
Почему бы вам просто не запустить свой пакетный файл из другого места?
Даже если вы не можете этого сделать, что вы можете сделать, так это создать файл, состоящий всего из одной строки, вызывающий другой пакетный файл, который не удаляется.Этот файл выполняет все - запуск программы Java, всю очистку и даже восстановление исходного пакетного файла, чтобы вы могли запускать его несколько раз.
Вместо запуска launch.bat через cmd /c launch.bat
, который попытается передать управление обратно вызывающему пакетному файлу, когда это будет сделано, запустите его, просто выполнив: launch.bat
Это передаст управление (думайте об этом как о переходе вместо вызова) в командный файл, поэтому он не будет пытаться вернуть управление файлу, который больше не существует.
Можно выполнить строки из удаленного файла, но строки должны находиться в блоке, заключенном в круглые скобки, поскольку блоки всегда полностью кэшируются в памяти перед их выполнением.
Очевидно, что вы не можете вызывать функции в пакете, но можно вызвать другие пакетные файлы и вернуть управление обратно (в блок).
@echo off
(
echo Delete myself
del %~f0
call ..\second.bat
echo do some other stuff after second.bat
)
echo This line can't be reached anymore