Batch file to delete calling program and then itself There are times when I want to run a one-off executable on an end-user's machine that cleans up after itself, i.e. deletes itself without a trace. An exe can't delete itself because an exe can't be deleted while it's running. However, a batch file can delete itself, presumably because its contents get copied so the file can close before the code gets run.

So what if there was a general-purpose batch file that deletes the calling executable and then deletes itself? I couldn't find such a batch file so I made one, thinking maybe it could be useful to others. And obviously I want to see if it can be improved upon, of course.

This is particularly useful for an NSIS installer because the batch file can be embedded in the exe and then extracted.

Make sure you copy the batch file before you test it because it will delete itself!

@ECHO OFF

SET filename=%~nx1

IF "%filename%"=="" GOTO:EOF

TASKKILL /IM "%filename%" /F

:LOOP
TASKLIST | FIND /I "%filename%" &gt;NUL 2&gt;&amp;1
IF ERRORLEVEL 1 (
  GOTO CONTINUE
) ELSE (
  ECHO %filename% is still running
  PING -n 6 127.0.0.1&gt;NUL
  GOTO LOOP
)

:CONTINUE

DEL /F "%~f1"
DEL /F "%~f0"


I figured the easiest way to get the path of the calling program is to just have it passed in as a parameter. The IF "%filename%"=="" GOTO:EOF is very important because if the first parameter isn't defined then DEL /F "%~f1" will automatically act like a * is there and try to delete the contents of the whole folder.
TASKKILL /IM "%filename%" /F


It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.



Comments would be great. 

For example, I understand that PING -n 6 127.0.0.1&gt;NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.



Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated. 

There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.



GOTO CONTINUE


Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it. 



) ELSE (


This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is 

:LOOP
TASKLIST | FIND /I "%filename%" &gt;NUL 2&gt;&amp;1
IF ERRORLEVEL 1 (
  GOTO CONTINUE
)
ECHO %filename% is still running
PING -n 6 127.0.0.1&gt;NUL
GOTO LOOP


Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.

:LOOP
TASKLIST | FIND /I "%filename%" &gt;NUL 2&gt;&amp;1
IF ERRORLEVEL 0 (
  ECHO %filename% is still running
  PING -n 6 127.0.0.1&gt;NUL
  GOTO LOOP
)


I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.