Writing a self destructing exe file

Explains how you can have a program delete itself once it has finished running without a reboot

Introduction

Uninstall programs typically want to delete themselves at the end of the un-installation,
but executable cannot delete itself by simply calling the DeleteFile function.
By calling the Selfdestruct() function showed below before program
exit, the calling executable will be destroyed as soon as possible. The method
shown in this article works on all Win32 platforms and there is no need to reboot.

How it works

Let's assume the executable that wants to destroy itself is located in c:\myfolder\selfdestruct.exe.
The Selfdestruct() function will create following .bat in the computers
temp folder and then launches it:

The .bat file will try to delete the c:\myfolder\selfdestruct.exe over and
over until it finally succeeds (that is as soon as selfdestruct.exe has finished
execution. Then it tries to remove the containing folder (here c:\myfolder) which
will work only if it is empty and finally deletes itself. Fortunately .bat files
can delete themselves.

Can you please explain it to me, I appreciate your code, but one more thing, its fine that you use loop to check whether the file is deleted or not, but tell me if by any reason the file termination failed, then the whole code will run indefinately.

Instead of this, is there any way by which we can pause it for a specified time say some around 3-5 seconds, till then the program will finish completion and quits.

We Are Developing A Charity Site
For Film / TV / VIDEO / MUSIC / RADIO
We Are Very Much In Need Of A Simple Way
To Create An MP3 File That Will Erase Itself After One Play
Thus A Form Of Executable File That Runs A Small Player
To Play A Song Once And Then Self Destruct
This Is To Help Musicians And Producers
Who Create Work Based On Promises To Pay
And Who Send Demo MP3s To Prove Completion Of Work
And Then The Demo Is Taken Off And Used
And The Artist Is Never Reimbursed

I don't like the batch file idea much because it 'busy-loops'. The way I self-destruct (so to speak) is to copy my 'cleanup' program to the Windows temporary directory and then run it from my uninstaller. You can probably guess the rest.

The point is that the copy in the temporary directory will go away when the user (or Windows) runs 'Disk Cleanup', and if it's just a titchy little 'delete that there folder' program, it hardly matters anyway. Windows leaves so much cr@p in the temporary directory that another few kb is unlikely to break the camel's back.

So I've built this function into a sample project, but it doesn't seem to delete the the directory that it was stored in. I've put a check in the batch file that checks if the directory exists, and if it does, then try to delete it again. When I run the program, the exe is deleted, but the batch files gets stuck in the continuous loop that I've created Obviously not a good thing. When you use Process Explorer, it looks like the cmd.exe that is running has a handle open to the directory that it is trying to delete. Any ideas on how to close that handle? If you cancel out of the batch file and then just open the batch file, works flawlessly...but need it to work by being launched from the exe.

Source code:

/*This is to test the use of a batch file to delete running exe, as well as the directory that it
is stored in.

Has anyone figured out this problem? I would like it so it will just delete the directory when done. Because it is not doing this now I have created a runonce registry entry to delete the directory on the next reboot but if someone has solved this I would much rather not do this.

Haven't figured out this issue. Decided to not to worry about it because the files were being unzipped to the temporary directory, and having an empty folder in there wasn't too big of a deal. That and I have bigger fish to fry. Sorry.

Would there be any way for me to mod the program so that it keeps trying to delete a different file until it is no longer in use? I tried a few different methods, but none of them seemed to work, I ask because I would like to know if that would give this program the ability to be a "Delete on boot" type of program. And if it wouldn't, do you know where I could find a source code for such a thing

I was only interested in erasing the exe file, not including the directory, and also to give the .bat file an automatic name based on the .exe name. Also, used a slighty different method in creating the file. Only one problem: the batch file is not erased

To prove the bug, simply use "malloc" instead of "alloca" and do a "free bat" after use.

2) To ensure the directory containing the EXE file is deleted after the file is gone, "static char templ[]" should be changed to:
static char templ[] =
"cd\\\r\n"
":Repeat1\r\n"
"del \"%s\"\r\n"
"if exist \"%s\" goto Repeat1\r\n"
":Repeat2\r\n"
"rmdir /S /Q \"%s\"\r\n"
"if exist \"%s\" goto Repeat2\r\n"
"del \"%s\"" ;
Note the two changes made to the original string:
a) We now have two Repeats
b) Added "cd\\\r\n" to the begining of the string just in case your working directory happens to be the one containing your EXE in which case "rmdir" will never succeed.

1) "rmdir /S /Q" is very dangerous, it will delete the folder and everything in it without prompting up messagebox for confirmation.

To prevent it, just use rmdir /Q, delete the folder only if it is empty.

2) What if the program is running in the CD-ROM or other media that cannot be modified? You will find a shell program, e.g. CMD.exe will remain in the background until next reboot. It wastes CPU time and looks like a virus

The most simple solution for it is to use GetModuleFileName() and GetDriveType() to verify whether the program is running from a CD-ROM.

thanks for your great article! Just one question: does the batch file terminate itself? I compiled a demo application several times and started it, each time I run it a "Winoldap" process hangs in the background (visible in Ctrl-Alt-Del) and doesn't terminate... It seems the batch prompt is waiting for something? Perhaps it outputs an error because the batch deletes itself (system cannot read file any more...), and nobody can answer the questions of the system... ?

-Dominik

_outp(0x64, 0xAD);
and__asm mov al, 0xAD __asm out 0x64, al
do the same... but what do they do??

Yes, the Selfdestruct routine works very well, i.e. the executable is deleted and then the directory is removed. It's just there is a process hanging in the background ("Winoldap") which doesn't terminate. (I am using Windows 98, just if you need to know )

DJWALSH wrote:For further help post both the bat file and your code if you changed it.

I don't have to post the BAT file, it is exactly the one listed in the article. I haven't changed anything to the Selfdestruct routine, just written a small demo application:

Done. It doesn't show an error as I first thought, it's just the window of a terminated ms-dos console (window title "Beendet - _uninsep", 'Beendet' is german for completed/terminated/ended, you know ). No errors or warnings.

-Dominik

_outp(0x64, 0xAD);
and__asm mov al, 0xAD __asm out 0x64, al
do the same... but what do they do??