Script batch che si elimina da solo
-
10-07-2019 - |
Domanda
Ho uno script .bat
che avvia un programma java
.
Il programma java
elimina la cartella in cui si trova .bat
.
Non ho modo di toccare il programma java
. Posso solo modificare il file .bat
.
Il problema è che il file .bat
, una volta eliminato, ne interrompe immediatamente l'esecuzione senza finire.
Ma ci sono alcune attività di pulizia da fare dopo la chiusura del programma java
.
Ho provato a copiare il file .bat
da qualche altra parte e lanciarlo in una posizione in cui non sarebbe stato eliminato. Purtroppo, una volta eliminato il .bat
originale, poiché è ancora in esecuzione, si verifica lo stesso crash e non termina.
Ecco due file di esempio (ai fini dell'esempio, facciamo finta che si trovino in 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"
Il lancio di launch.bat
funzionerebbe se l'esecuzione del launch.bat
copiato fosse separata da quella iniziale.
Qualcuno sa come fare in modo che un .bat
termini la sua esecuzione anche se viene eliminato mentre viene eseguito?
Soluzione 4
Sembra che io abbia un risultato migliore facendolo in questo modo (chiamando launch.bat
con 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"
Ora posso raggiungere echo " after delete "
, ma finisco in qualche modo in un ciclo infinito. Almeno la mia pulizia può essere eseguita a questo punto. Non so perché non riesco a raggiungere echo " launch end "
, tuttavia.
Altri suggerimenti
Questo comanderà allo script di cancellare se stesso e poi uscire. L'intera riga viene letta dall'interprete dei comandi prima dell'esecuzione della riga, quindi il comando di uscita verrà eseguito dopo il comando di eliminazione anche se il file non esiste più.
del /f/q "%~0" | exit
In alternativa, puoi usare le parentesi se vuoi eseguire molti comandi dopo che il file è stato cancellato poiché l'interprete dei comandi leggerà tutto tra parentesi prima di eseguirlo.
(del /f/q "%~0"
if exist "%~0" (echo.How did that happen?) else (echo.I've deleted myself.)
pause
exit)
Qualcuno sa come fare in modo che un .bat finisca la sua esecuzione anche se viene eliminato mentre viene eseguito?
Non penso sia possibile. Esecuzione batch letta direttamente dal file. Se modifichi il file, cambierà l'esecuzione (i programmi batch auto-modificanti sono meravigliosamente difficili da eseguire il debug!)
Perché non avviare il file batch da una posizione diversa?
Anche se non puoi farlo, quello che puoi fare è avere un file costituito da una sola riga, chiamando un altro file batch che non viene eliminato. Questo file fa tutto, avviando il programma java, eseguendo tutte le operazioni di pulizia e includendo anche il ripristino del file batch originale in modo da poterlo eseguire più volte.
Invece di eseguire launch.bat tramite un cmd / c launch.bat
, che al termine tenterà di trasferire il controllo al file batch chiamante, eseguendolo semplicemente: Launch.bat
Questo trasferirà il controllo (pensalo come un goto anziché una chiamata) al file batch, quindi non proverà a restituire il controllo a un file che non esiste più.
È possibile eseguire righe da un file eliminato, ma le righe devono risiedere in un blocco tra parentesi, poiché i blocchi vengono sempre memorizzati nella cache completamente in memoria prima di essere eseguiti.
Ovviamente non puoi chiamare funzioni nel batch, ma è possibile richiamare altri file batch e riavere il controllo (nel blocco).
@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