Win32 Self-Deletion Function

SelfDelete() is a simple Win API function for creating a self-deleting executable. It works by invoking the command shell as a serialized process to delete the program file.

The Command Shell

The command shell program is defined by the environment variable "COMSPEC". This varies with the Windows OS: Win9x/ME use COMMAND.COM, while WinNT/2K/XP use CMD.EXE. The following string is passed to the command shell:

/c del Filename > nul

which translates to: "Run a single command to delete a file and redirect the output to nowhere." Filename is the full path and name of the file we want to delete. This name needs to be converted into its short 8.3 name to change any extended characters into OEM equivalents.

The command shell is started as an independent process by calling the ShellExecuteEx() function. Its process handle is defined by the SHELLEXECUTEINFO struct member "hProcess". NOTE: The "/c" switch is necessary for the command shell process to exit. Do not omit it from the parameters string.

Serializing Processes

Self-deletion presents us with a special problem: The main program must exit and close its opened file handle before the command shell deletes the file. To do this, we must serialize two independent, parallel processes—the current program process and the command shell process. This is done by manipulating CPU resource priorities to temporarily suppress the command shell process. As written, the code will allocate all CPU resources to the main program until it exits. This effectively blocks any command shell execution until the program has terminated.

CPU Allocation

Allocating the REALTIME_PRIORITY_CLASS and THREAD_PRIORITY_TIME_CRITICAL settings can interfere with driver functions and can cause Windows to "hang" if kept in a prolonged state. To avoid these problems, a self-deleting app must exit cleanly upon a boolean return of TRUE. Developers need to make sure all ancillary processes and threads have finished and all handles are closed before calling the function. SelfDelete() should only be called at a program's main exit:

  INT APIENTRY WinMain(...)

    // on program exit
    // close all handles etc.
      // add error messaging
    return 0;    // WinMain exit

It may be desirable to use a lower CPU allocation, such as:


This allocation does not guarantee a complete cessation of the command shell process, but nevertheless works well.

Code Limitations

  • There is no error checking if the command shell cannot delete the file. Make sure the program file is not set with a "hidden," "system," or "read-only" attribute.
  • The explorer shell will always remove the program icon from view regardless of whether the command shell is able to actually delete the file. Pressing F5 will update the shell folder and correct any erroneous listings.
  • The command shell can only run a single command. Multiple commands such as to delete a file and remove its directory cannot be done without a script file.


The code has been modified to work better on NT kernel computers with multiple processors. Windows allocates resources through a thread priority queue rather than by time-slicing CPU cycles. Two modifications have been made to the code:

  • The thread allocation to the program process has been increased prior to invoking the command shell process. This ensures the program process will always have priority in the resource queue. Threads created by the ShellExecuteEx function do not inherit the resource allocation of the calling process.
  • The NT kernel will transiently increase priority to whatever process is granted CPU resources. The SetProcessPriorityBoost function has been added to prevent this from happening to the command shell process.

#include <windows.h>
#include <shlobj.h>

BOOL SelfDelete()

  TCHAR szModule [MAX_PATH],
        szParams [MAX_PATH];

  // get file path names:
  if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&
     (GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&
    // set command shell parameters
    lstrcpy(szParams,"/c del ");
    lstrcat(szParams, szModule);
    lstrcat(szParams, " > nul");

    // set struct members
    sei.cbSize       = sizeof(sei);
    sei.hwnd         = 0;
    sei.lpVerb       = "Open";
    sei.lpFile       = szComspec;
    sei.lpParameters = szParams;
    sei.lpDirectory  = 0;
    sei.nShow        = SW_HIDE;
    sei.fMask        = SEE_MASK_NOCLOSEPROCESS;

    // increase resource allocation to program

    // invoke command shell
      // suppress command shell process until program exits

      // notify explorer shell of deletion
      return TRUE;
    else // if error, normalize allocation
  return FALSE;


Download source - 4 Kb


  • PERL solution

    Posted by Legacy on 09/16/2003 12:00am

    Originally posted by: David Ross

    I need this to happen from within a PERL program.

    Any ideas?

  • When ShellExecute is finished

    Posted by Legacy on 08/10/2003 12:00am

    Originally posted by: Dave

    How do we know when the program that we executed is finished

  • Why so complicated solution?

    Posted by Legacy on 06/12/2003 12:00am

    Originally posted by: Jan

    If you spawn batch "deleteme.bat" file with:

    del yourfile.exe
    if exist yourfile.exe goto Repeat
    del deleteme.bat

    The last line will safely delete the batch file.

    Regards, Jan

  • Good work

    Posted by Legacy on 06/11/2003 12:00am

    Originally posted by: Halid

    its good work.

  • Ultimatly needed for some specific cases

    Posted by Legacy on 05/30/2003 12:00am

    Originally posted by: Ponn Periasamy

    Win32 Self-Deletion Function helps more.
    Ultimatly needed for some specific cases

  • What happens on a dual processor machine?

    Posted by Legacy on 04/07/2003 12:00am

    Originally posted by: Vadim

    You cannot guarantee the first process will stop before the second one starts in this case.

  • works greate

    Posted by Legacy on 03/31/2003 12:00am

    Originally posted by: gok

    in your cpp just add
    #include <shellapi.h>

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there's simply not enough quality talent to go around. In response, companies often resort to inferior solutions -- hiring substandard developers and engineers, recruiting talent on a part-time or temporary basis, poaching people from competitors, or burdening an already stressed IT staff for more of their labor. Fortunately, there's a better solution. Read this white paper to learn the business value of …

  • On-demand Event Event Date: September 23, 2015 The cloud is not just about a runtime platform for your projects – now, you can do your development in the cloud, too. Check out this webcast to learn how the cloud improves your development experience and team collaboration. Join Dana Singleterry, Principal Product Manager for Oracle Dev Tools, as he discusses how to simplify every aspect of the development lifecycle, including requirements gathering, version management, code reviews, build automation, and …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date