views:

194

answers:

3

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 ?

A: 

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.

Mark Byers
Adding another file somewhere else is unfortunately not an option in this case. I have access only to the very folder which is being deleted, so I would create another file reaching to the same kind of crash.
subtenante
Perhaps you can open the batch file in Word (or using some other mechanism) to force an exclusive lock on the file, then when the Java program tries to delete it, the deletion will fail.
Mark Byers
Interestingly, if I set launch.bat to read only, it can't be deleted by delete.bat, but I still never reach `echo "launch end"`.
subtenante
A: 

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.

Ferruccio
I actually added the `cmd /c` after I witnessed that calling directly launch.bat caused the same problem.
subtenante
Calling with `cmd /k`is slightly better because I can see the echo "delete end", but I still can't reach "launch end".
subtenante
What I'm saying is that the launch.bat command should be the very last thing the batch file does, any cleanup code should go into launch.bat.
Ferruccio
A: 

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.

subtenante