script em lotes excluindo-se
-
10-07-2019 - |
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?
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