Question

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 finish.

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?

Was it helpful?

Solution 4

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.

OTHER TIPS

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)   

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'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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top