Pergunta

Eu tenho um script .bat lançar um programa java. O programa java exclui a pasta onde o .bat senta. Eu não tenho nenhuma maneira de tocar o programa java. Eu só pode modificar o arquivo .bat.

O problema é que o arquivo .bat, uma vez excluído, pára a sua execução imediatamente, sem acabamento. Mas há algumas tarefas de limpeza a ser feito após o programa termina java.

Eu tentei copiar o arquivo .bat em outro lugar e lançá-lo em um local onde ele não seria eliminado. Infelizmente, uma vez que o .bat original é excluído, porque ele ainda está em execução, o mesmo acidente acontece e não terminar.

Aqui estão dois arquivos de amostra (para a finalidade do exemplo, vamos fingir que eles estão localizados em 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"

O lançamento launch.bat funcionaria se a execução do launch.bat copiados foram separados do inicial.

Alguém sabe uma maneira de fazer uma final .bat até sua execução, mesmo se ele for excluído enquanto ele executa?

Foi útil?

Solução 4

Parece que tenho um melhor resultado ao fazê-lo assim (chamando launch.bat com 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"

Agora eu posso alcançar o echo "after delete", mas eu acabar de alguma forma em um loop infinito. Pelo menos o meu a limpeza pode ser executado neste momento. Não sei por que eu não posso chegar echo "launch end", no entanto.

Outras dicas

Isto irá comandar o script para excluir-se, em seguida, sair. Toda a linha é lida pelo interpretador de comandos antes da linha é executada assim que o comando de saída será executado após o comando delete mesmo que o arquivo não existe mais.

del /f/q "%~0" | exit

Como alternativa, você pode usar parênteses se você quer executar muitos comandos após o arquivo foi apagado como o comando intérprete irá ler tudo dentro dos parênteses antes de executá-lo.

(del /f/q "%~0"
if exist "%~0" (echo.How did that happen?) else (echo.I've deleted myself.)
pause
exit)   

Alguém sabe uma maneira de fazer uma final .bat até sua execução, mesmo se ele for excluído enquanto ele executa?

Eu não acho que isso é possível. execução em lote ler diretamente do arquivo. Se você modificar o arquivo, ele vai mudar a execução (programas de lote auto-modificando são maravilhosamente difícil de depuração!)

Por que você não apenas iniciar o seu arquivo de lote a partir de um local diferente?

Mesmo que você não pode fazer isso, o que você pode fazer é ter um arquivo composto por apenas uma única linha, chamar outro arquivo em lotes que não são apagados. Este arquivo faz tudo -. Iniciar o programa java, fazendo tudo a limpeza, e mesmo incluindo restaurar o arquivo original do lote, para que você possa executá-lo várias vezes

Em vez de correr launch.bat através de um cmd /c launch.bat, que vai tentar controlar a transferência de volta para o arquivo batch chamando quando ele é feito, executá-lo, basta fazer: launch.bat Isto irá transferir o controle (pense nisso como um goto, em vez de uma chamada) para o arquivo de lote, por isso não vou tentar retornar o controle para um arquivo que não existe mais.

É possível executar as linhas de um arquivo excluído, mas as linhas têm de residir em um bloco de parênteses, como blocos são sempre armazenados em cache completamente na memória antes de serem executadas.

Obviamente você não pode chamar funções no lote, mas é possível chamar outros arquivos em lote e começar a recuperar o controle (no bloco).

@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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top