Click here to Skip to main content
16,012,468 members
Articles / Desktop Programming / MFC
Article

Writing a self destructing exe file

Rate me:
Please Sign up or sign in to vote.
4.23/5 (29 votes)
26 Apr 2003Public Domain 190.7K   61   30
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.

Using the code

Just call the Selfdestruct() function before program exit.

// this is the name of the temporary .bat file
static const char tempbatname[] = "_uninsep.bat" ;

void Selfdestruct() 
{
  // temporary .bat file
  static char templ[] = 
    ":Repeat\r\n"
    "del \"%s\"\r\n"
    "if exist \"%s\" goto Repeat\r\n"
    "rmdir \"%s\"\r\n"
    "del \"%s\"" ;


  char modulename[_MAX_PATH] ;    // absolute path of calling .exe file
  char temppath[_MAX_PATH] ;      // absolute path of temporary .bat file
  char folder[_MAX_PATH] ;

  GetTempPath(_MAX_PATH, temppath) ;
  strcat(temppath, tempbatname) ;

  GetModuleFileName(NULL, modulename, MAX_PATH) ;
  strcpy (folder, modulename) ;
  char *pb = strrchr(folder, '\\');
  if (pb != NULL)
    *pb = 0 ;

  HANDLE hf ;
  
  hf = CreateFile(temppath, GENERIC_WRITE, 0, NULL, 
              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;
  
  if (hf != INVALID_HANDLE_VALUE)
  {
    DWORD len ;
    char *bat ;

    bat = (char*)alloca(strlen(templ) + 
               strlen(modulename) * 2 + strlen(temppath) + 20) ;

    wsprintf(bat, templ, modulename, modulename, folder, temppath) ;

    WriteFile(hf, bat, strlen(bat), &len, NULL) ;
    CloseHandle(hf) ;

    ShellExecute(NULL, "open", temppath, NULL, NULL, SW_HIDE);
  }
}

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:

:Repeat
del "c:\myfolder\selfdestruct.exe"
if exist "c:\myfolder\selfdestruct.exe" goto Repeat
rmdir "c:\myfolder"
del "c:\temp\_uninsep.bat" ;

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.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalfolder doesnot get deleted Pin
learningvisualc18-Mar-10 0:04
learningvisualc18-Mar-10 0:04 
QuestionWhat is this templ????????????? Pin
RAJEEV_RSD24-Sep-09 23:05
RAJEEV_RSD24-Sep-09 23:05 
AnswerRe: What is this templ????????????? Pin
Michael Walz24-Sep-09 23:44
Michael Walz24-Sep-09 23:44 
Generalbat file Pin
tetadenovicia26-Jun-08 7:09
tetadenovicia26-Jun-08 7:09 
QuestionSelf-Destructing Files Pin
tao17-May-08 10:56
tao17-May-08 10:56 
GeneralHere's another safe and simple way Pin
Paul Sanders (the other one)20-Oct-07 7:02
Paul Sanders (the other one)20-Oct-07 7:02 
QuestionIssue with deleting the directory Pin
ccoffman9729-Dec-06 5:52
ccoffman9729-Dec-06 5:52 
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 Frown | :( 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.

Selfdestruct function was pulled from
http://www.codeproject.com/file/cpselfdestruct2.asp
*/

#include <windows.h>
#include <tchar.h>
#include <malloc.h>

void Selfdestruct();
static const char tempbatname[] = "cleanup.bat" ;

void main(void)
{
Selfdestruct();

}

void Selfdestruct()
{
// temporary .bat file
static char templ[] =
":Repeat\r\n"
"del \"%s\"\r\n"
"if exist \"%s\" goto Repeat\r\n"
":Repeat2\r\n"
"rmdir \"%s\"\r\n"
"if exist \"%s\" goto Repeat2\r\n"
"del \"%s\"";

char modulename[_MAX_PATH] ; // absolute path of calling .exe file
char temppath[_MAX_PATH] ; // absolute path of temporary .bat file
char folder[_MAX_PATH] ;

GetTempPath(_MAX_PATH, temppath) ;
strcat(temppath, tempbatname) ;

GetModuleFileName(NULL, modulename, MAX_PATH) ;
strcpy (folder, modulename) ;
char *pb = strrchr(folder, '\\');
if (pb != NULL)
*pb = 0 ;

HANDLE hf ;

hf = CreateFile(temppath, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;

if (hf != INVALID_HANDLE_VALUE)
{
DWORD len ;
char *bat ;

bat = (char*)alloca(strlen(templ) +
strlen(modulename) * 2 + strlen(temppath) * 4) ;
/*bat = (char*)alloca(strlen(templ) +
strlen(modulename) * 2 + strlen(temppath) + strlen(folder) + 20) ;*/


wsprintf(bat, templ, modulename, modulename, folder, folder, temppath) ;

WriteFile(hf, bat, strlen(bat), &len, NULL) ;
CloseHandle(hf) ;
ShellExecute(NULL, "open", temppath, NULL, NULL, SW_SHOW);
return;
}
}
AnswerRe: Issue with deleting the directory Pin
SF123420-Feb-07 16:43
SF123420-Feb-07 16:43 
GeneralRe: Issue with deleting the directory Pin
ccoffman9721-Feb-07 3:09
ccoffman9721-Feb-07 3:09 
QuestionModification Question Pin
Dark_Xion1-Oct-06 6:51
Dark_Xion1-Oct-06 6:51 
GeneralI wrote something like this... Pin
Khan Shere18-Jan-05 21:22
Khan Shere18-Jan-05 21:22 
GeneralRe: I wrote something like this... Pin
Khan Shere21-Jul-05 7:59
Khan Shere21-Jul-05 7:59 
GeneralBug fixes and enhancements Pin
Dennis Jiang4-Jul-03 9:37
Dennis Jiang4-Jul-03 9:37 
GeneralRe: Bug fixes and enhancements Pin
amethystwu24-Oct-05 20:23
amethystwu24-Oct-05 20:23 
GeneralOther methods Pin
jmkhael28-Apr-03 3:34
jmkhael28-Apr-03 3:34 
GeneralRe: Other methods - Clickety Pin
Phil J Pearson29-Apr-03 7:06
Phil J Pearson29-Apr-03 7:06 
GeneralRe: Other methods: More Methods Pin
DoctorKoch14-Jan-07 23:40
DoctorKoch14-Jan-07 23:40 
GeneralReally really small article HTML bug Pin
Dominik Reichl27-Apr-03 9:26
Dominik Reichl27-Apr-03 9:26 
GeneralBatch doesn't terminate Pin
Dominik Reichl27-Apr-03 9:16
Dominik Reichl27-Apr-03 9:16 
GeneralRe: Batch doesn't terminate Pin
jlap77727-Apr-03 13:45
jlap77727-Apr-03 13:45 
GeneralRe: Batch doesn't terminate Pin
Dominik Reichl28-Apr-03 6:45
Dominik Reichl28-Apr-03 6:45 
GeneralRe: Batch doesn't terminate Pin
DJWALSH28-Apr-03 2:08
DJWALSH28-Apr-03 2:08 
GeneralRe: Batch doesn't terminate Pin
Dominik Reichl28-Apr-03 6:43
Dominik Reichl28-Apr-03 6:43 
GeneralRe: Batch doesn't terminate Pin
Michael Walz28-Apr-03 6:50
Michael Walz28-Apr-03 6:50 
GeneralRe: Batch doesn't terminate Pin
Dominik Reichl28-Apr-03 7:49
Dominik Reichl28-Apr-03 7:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.