Batch script deleting itself
I have a .bat
script launching a java
program.
The java
program deletes the folder where the .bat
sits.
I have no way to touch the java
program. I only can modify the .bat
file.
The problem is that the .bat
file, once deleted, stops its execution right away without finishing.
But there are some cleanup tasks to be done after the java
program exits.
I tried to copy the .bat
file somewhere else and launch it in a location where it would not be deleted. Alas, once the original .bat
is deleted, because it is still in execution, the same crash happens and it does not fini开发者_Python百科sh.
Here are two sample files (for the purpose of the example, let's pretend they are located 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"
Launching launch.bat
would work if the execution of the copied launch.bat
were separated from the initial one.
Does anyone know a way to make a .bat
end up its execution even if it is deleted while it executes?
This will command the script to delete itself then exit. The entire line is read by the command interpreter before the line is executed so the exit command will be executed after the delete command even though the file no longer exists.
del /f/q "%~0" | exit
Alternatively, you can use parentheses if you want to execute many commands after the file has been deleted as the command interpreter will read everything inside the parentheses before executing it.
(del /f/q "%~0"
if exist "%~0" (echo.How did that happen?) else (echo.I've deleted myself.)
pause
exit)
It's possible to execute lines from a deleted file, but the lines have to reside in a parenthesis block, as blocks are always cached completly into memory before they are executed.
Obviously you can't call functions in the batch, but it's possible to call other batch files and get the control back (into the block).
@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
Does anyone know a way to make a .bat end up its execution even if it is deleted while it executes ?
I don't think it is possible. Batch execution read directly from the file. If you modify the file, it will change the execution (self-modifying batch programs are wonderfully difficult to debug!)
Why don't you just start your batch file from a different location?
Even if you can't do that, what you can do is to have a file consisting of only a single line, calling another batch file that doesn't get deleted. This file does everything - starting the java program, doing all the clean up, and even including restoring the original batch file so that you can run it multiple times.
Instead of running launch.bat via a cmd /c launch.bat
, which will try to transfer control back to the calling batch file when it's done, run it by simply doing: launch.bat
This will transfer control (think of it as a goto instead of a call) to the batch file, so it wont try to return control to a file that no longer exists.
It seems I have a better result by doing it like this (calling launch.bat
with 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"
Now I can reach the echo "after delete"
, but I end up somehow in an infinite loop. At least my clean up can be executed at this point. Don't know why I can't reach echo "launch end"
, though.
精彩评论