Пакетный скрипт удаляет себя - PullRequest
0 голосов
/ 30 ноября 2009

У меня есть скрипт .bat, запускающий программу java. Программа java удаляет папку, в которой находится .bat. У меня нет возможности прикоснуться к программе java. Я могу изменить только файл .bat.

Проблема в том, что файл .bat после удаления сразу останавливает его выполнение без завершения. Но есть некоторые задачи очистки, которые нужно выполнить после выхода из программы java.

Я попытался скопировать файл .bat в другое место и запустить его в месте, где он не будет удален. Увы, после удаления оригинального .bat, поскольку он все еще выполняется, происходит такой же сбой, и он не завершается.

Вот два примера файлов (для примера давайте представим, что они находятся в D:\tmp):

delete.bat

echo "delete start"

pause

del launch.bat

pause

echo "delete end"

launch.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 завершить выполнение, даже если он был удален во время выполнения?

Ответы [ 5 ]

3 голосов
/ 30 апреля 2013

Это заставит скрипт удалить себя, а затем выйти. Вся строка читается интерпретатором команд перед ее выполнением, поэтому команда выхода будет выполнена после команды удаления, даже если файл больше не существует.

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)   
0 голосов
/ 30 апреля 2013

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

Очевидно, что вы не можете вызывать функции в пакете, но можно вызвать другие пакетные файлы и вернуть элемент управления (в блок).

@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
0 голосов
/ 30 ноября 2009

Вместо запуска launch.bat через cmd /c launch.bat, который попытается передать управление обратно в вызывающий пакетный файл, когда это будет сделано, запустите его, просто выполнив: launch.bat Это передаст управление (воспринимается как переход, а не вызов) в командный файл, поэтому он не будет пытаться вернуть управление в файл, который больше не существует.

0 голосов
/ 30 ноября 2009

Кажется, у меня есть лучший результат, если я сделаю это так (вызов launch.bat с cmd /k):

launch.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".

0 голосов
/ 30 ноября 2009

Кто-нибудь знает способ заставить .bat завершить выполнение, даже если он был удален во время выполнения?

Я не думаю, что это возможно. Пакетное выполнение читается прямо из файла. Если вы измените файл, он изменит исполнение (самоизменяющиеся пакетные программы чудесно трудны для отладки!)

Почему бы вам просто не запустить пакетный файл из другого места?

Даже если вы не можете этого сделать, вы можете создать файл, состоящий всего из одной строки, который вызывает другой пакетный файл, который не удаляется. Этот файл делает все - запускает java-программу, выполняет очистку и даже включает восстановление исходного пакетного файла, чтобы вы могли запустить его несколько раз.

...