42

Is there any way that a running process can delete its own executable?

For example, I make a console application (single exe) and after doing some tasks it somehow deletes the exe file.

I have to send a single file to someone. And I want it deleted after it does its intended task.

Is there anyway to do it in Windows

ata
  • 8,853
  • 8
  • 42
  • 68
  • I have seen that a msi uninstall DOES delete the executable from disc, even while its running. I don't know how this happens, but the file explorer does not show the file any more at least, and in our case, the running application crashes with some access violation exception - but the process is still running after the file has gone! I personally find a way to avoid this behavior, but I can't find out, how to delete it in the way the msi does it ... – Lumo Jun 02 '20 at 13:30
  • See [Self-deleting Executables](http://www.catch22.net/tuts/win32/self-deleting-executables#) for all kinds of different ways to accomplish this. – Remy Lebeau Aug 10 '21 at 01:58

9 Answers9

25

One way to do this is to use the MoveFileEx function with the MOVEFILE_DELAY_UNTIL_REBOOT flag and a NULL destination. According to the documentation, this:

registers the lpExistingFileName file to be deleted when the system restarts. If lpExistingFileName refers to a directory, the system removes the directory at restart only if the directory is empty.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 3
    I do not understand why we can't delete it because exe gets loaded to RAM ,so why does it require to communicate with hard drive ? – Xinus Oct 22 '09 at 10:10
  • 12
    Windows only loads as much of the executable as it needs to, so that it doesn't (a) use up too much RAM or (b) have to write the executable out to the swap file again if there isn't enough RAM. You can think of each executable being run by Windows as a temporary read-only swap file. If a page of RAM needs to be discarded, Windows can simply discard it knowing that it can always be reloaded from the EXE file when necessary. – Greg Hewgill Oct 22 '09 at 10:16
  • 2
    This method is too reliant on restart. No doubt it would work, but I wanted to delete the file as soon as I can. – ata Oct 26 '09 at 05:51
  • 1
    @GregHewgill The problem is not really demand-paging - Linux does that too, but supports deleting running executables. Since it's possible to mirror that behavior for regular files, it seems like a deliberate limitation for executables on Windows. – lxgr Aug 29 '13 at 10:17
  • 1
    In recent versions of Windows, this requires admin privileges. – Hut8 Dec 02 '15 at 02:53
25
process.start("cmd /c ping localhost -n 3 > nul & del filepath")
exit

Explanation :

ping localhost -n 3

Adds a slight delay before executing del filepath. By the time it's triggered, your program has exited.

Replace process.start with whatever command your programming language uses to start programs with arguments.

Replace filepath with the path to your exe.

Replace exit with the command for terminating your program.

===

10yr anniverary edit, if this doesn't work, you must find a way to perform a "process.start" that starts a separate (external) process, not one subordinate to your original calling program: Python, Bash, C, ...... or search for a different language

Replace the search in the catch all with your programming language and you will likely find a suitable guide for this essential step. Please take care to ignore superfluous information as every question may come with obscure specific details that are unrelated to you.

Samie Bencherif
  • 1,285
  • 12
  • 27
  • 3
    If you are not using XP, you can avoid the ping-workaround by passing ""/C choice /C Y /N /D Y /T 3" (the cmd-command itself will wait 3 secinds): https://www.codeproject.com/Articles/31454/How-To-Make-Your-Application-Delete-Itself-Immedia – maja Mar 02 '18 at 11:18
9

You can use windows scheduler to schedule a task to delete your program after X seconds.

Command line: http://msdn.microsoft.com/en-us/library/bb736357%28VS.85%29.aspx

Or API: http://msdn.microsoft.com/en-us/library/aa383608%28VS.85%29.aspx

Alex Reitbort
  • 13,504
  • 1
  • 40
  • 61
4

You can run another application, which would wait for parent process to terminate, and then delete its executable.

Pavel Alexeev
  • 6,026
  • 4
  • 43
  • 51
4

It's possible to do this on Linux. You'll find that it is generally not possible to delete a running executable on Windows. However, you can have Windows delete the EXE for you on the next reboot: http://www.howtodothings.com/computers/a1402-delete-a-running-exe.html

If you want the file deleted after it's been run, you could simply ask the user to delete it. If the reason you want this is as a security measure, then what you're doing is misguided. The user could circumvent this by simply making a copy of the file first.

uckelman
  • 25,298
  • 8
  • 64
  • 82
  • Of course, this feature (along with stuff like hidden / system files etc.) also saved a lot of user data (and the system itself) when the user mistakenly does the equivalent of `rm -rf /`. It's a bit unnerving to me how unix systems don't tend to bat an eyelash and just get rid of *everything*. If you think you have to be really stupid to do this, just look at how many *nix shell scripts / applications you can google for "XXX has deleted all my data". Including high profile software like Steam :D It doesn't help that you specify the `-rf` before the path - `/`/`\` is quite close to `enter`. – Luaan Mar 31 '15 at 08:09
  • 1
    @Luaan Most modern *nix systems will actually bat an eyelash. Try `rm -rf /` on just about any system and it'll refuse unless you explicitly add `--no-preserve-root`. Obviously, try it on a VM, just in case, as it's possible your system's `rm` doesn't do that check, but many do. – Nic Jun 17 '19 at 14:24
3

While it's not possible to self delete a file when it's running it is possible to launch a detached cmd command from the file, then end the file operation before the command executes. So, if you want to delete a bat file you can just add at the end of the file the line: start cmd /c del %0 and the file would self destruct.

The start cmd will start a new cmd window (detached from your main process). The /c tells the windows to execute whatever comes after the /c in the line. Then the del will delete the file at the path it is given. The parameter $0 refers to the first command line argument which is usually the name and path to the file that was executed, which is what we want. (the $0 parameter is the path to the file, you want to pass that to the del command).

Gur Telem
  • 706
  • 1
  • 7
  • 14
0

Until that exe is in memory, it will not be able to delete itself. However, it can register with the system a task for deleting itself after a set time period of gap when it would be expected to be completing its execution.

techzen
  • 2,895
  • 2
  • 22
  • 22
0

I solved this problem (using Visual Basic) by creating a batchfile that is executed while the process is still running, waits 1sec so the program can close itself and than deletes the program.

You might need to modify it for this will delete every thing in the same folder. After your task just call del() and it should work.

 Sub del()
    Dim file As System.IO.StreamWriter
    file = My.Computer.FileSystem.OpenTextFileWriter("del.bat", True)
    file.WriteLine("")
    file.WriteLine("timeout 1")
    file.WriteLine("echo Y | del *.*")
    file.Close()
    Process.Start("del.bat")
    Me.Close()
End Sub
Julian
  • 33,915
  • 22
  • 119
  • 174
0

I couldn't find any solutions anywhere else so I'll post my fix here.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char* process_name = argv[0];
    char command[256] = "start /min cmd /c del ";
    strcat(command, process_name);

    printf("Attempting to delete self...\n");

    system(command);
    return 0;
}

Normally, trying to use system to call the command prompt to delete an executable would not work because the command prompt that is spawned is a child process that system executes and waits for a return status.

This method calls the system to start a command prompt process on its own thread.

The /min argument starts the process as "hidden".
The /c argument supplies arguments to the spawned command prompt.

I know this is an old thread, but I hopes those that come here in the future.

0xvpr
  • 1
  • 1
  • 2