I came across this problem in one of my test papers.
It says : Write a program that deletes itself( the exe file ) when run.

Here's my first attempt and it didn't work, so I added the error-checking code.

/* This program tries to delete itself */

#include <stdio.h>
#include <conio.h>
#include <errno.h>

int main( int argc, char *argv[] )
{
	printf("This program will delete itself. Press a key to continue...");
	getch();
	if( remove( argv[0] ))   // remove() returns non-zero on error
	{
		printf("\nSome error has occcurred. Couldn't delete file. Error :");
		switch( errno )
		{
			case EACCES : printf("Permission denied");
							break;
   			default : printf("Unknown error.");
   		}
	}
	else
		printf("\nFile %s deleted", argv[0] );
	getch();
    return 0;
}

The output is always "Permission Denied". Is there any other way to write this program?

#include <stdio.h>
#include <iostream>

using namespace std;
int main(int argc, char *argv[])
{
	if(remove(argv[0]) == -1)
	{
             cout << "Error deleting file\n";
	}
        else
	{
             cout << "File is gone!\n";
	}
	
  return (0);
}

This worked for me. I run linux, so it may be an OS thing, I remember windows not letting you delete files in use, so that may be the reason. Good Luck!

-r

...I remember windows not letting you delete files in use, so that may be the reason...

Windows does have that on files (to where you can't delete a file in use).

What you want to accomplish is more than likely possible, but you would have to trick Windows a little bit...if it is possible.

Now that is a REALLY clever way, probably a bit too much. I was looking for somwthing simpler.

Could you try this and see if it works?

#include <iostream>
using namespace std;


void del_me()
{
        // change the next line
	system("CommandToDeleteYourProgram");
}


int main()
{

	atexit(del_me);
    	
	return (0);
}

Give it a try. Good Luck!

-r

I tried that. I doesn't work. The o/p is still the same. If the problem lies with the OS, I guess there isn't much we can do.

I'd say it's platform independant. Most platforms have a lock on files that are in use, and you can't delete them:

#include <cstdlib>
#include <cstdio>

int main(int argc, char * * argv)
{
   remove(argv[0]);
   return EXIT_SUCCESS;

}

If that doesn't work, then as someone already mentioned, then it's got a lock on the file.


Maybe if you could find a renowned virus writer the question could be answered ;)

Try this for Windows. It writes itself a Batch File and runs it. After the Exe File is deleted, the batch file also deletes itself. A reboot isnt needed here.

#include <iostream>
#include <fstream.h>
#include <windows.h>
#include <shellapi.h>
int main( int argc, char* argv[] ) 
{
	char ExeFileName[ 260 ] = "";
	char BatFileName[ 260 ] = "";
	strncpy( ExeFileName, argv[ 0 ], strlen( argv[ 0 ] ) + 1);
	strncpy( BatFileName, argv[ 0 ], strlen( argv[ 0 ] ) + 1 );
	char* SlashPos = strrchr( BatFileName, '\\' );
	strncpy( SlashPos, "\\BatFileName.bat", strlen("\\BatFileName.bat" )  + 1  );
	ofstream BatFile(BatFileName);
	BatFile << ":Begin" << "\n";
	BatFile << "del " << ExeFileName << "\n";
	BatFile << "if exist " << ExeFileName << " goto Begin" << "\n";
	BatFile << "del " <<  BatFileName << "\n";
	BatFile.close();
	ShellExecute(NULL, "open", BatFileName, NULL, NULL, SW_HIDE);
	return 0;
}

This is a Windows problem - Windows has an answer:

The MoveFile API allows you to defer the action until reboot, so you can move the file to NULL: or wherever.

The
MOVEFILE_DELAY_UNTIL_REBOOT -
flag is specifically meant for files like dll's and pagefiles that remain open all the time.

Try this for Windows. It writes itself a Batch File and runs it. After the Exe File is deleted, the batch file also deletes itself. A reboot isnt needed here.

#include <iostream>
#include <fstream.h>
#include <windows.h>
#include <shellapi.h>
int main( int argc, char* argv[] ) 
{
	char ExeFileName[ 260 ] = "";
	char BatFileName[ 260 ] = "";
	strncpy( ExeFileName, argv[ 0 ], strlen( argv[ 0 ] ) + 1);
	strncpy( BatFileName, argv[ 0 ], strlen( argv[ 0 ] ) + 1 );
	char* SlashPos = strrchr( BatFileName, '\\' );
	strncpy( SlashPos, "\\BatFileName.bat", strlen("\\BatFileName.bat" )  + 1  );
	ofstream BatFile(BatFileName);
	BatFile << ":Begin" << "\n";
	BatFile << "del " << ExeFileName << "\n";
	BatFile << "if exist " << ExeFileName << " goto Begin" << "\n";
	BatFile << "del " <<  BatFileName << "\n";
	BatFile.close();
	ShellExecute(NULL, "open", BatFileName, NULL, NULL, SW_HIDE);
	return 0;
}

That's pretty clever ;)

Thanks, but don't know much about the windows API. I'm pretty sure it works...so thanks again :)

Hey, that works! Thanks a lot. But I didn't understand the ShellExecute() function. Does it run after the program terminates?

The ShellExecute API is used to perform an operation on a specifed file. In this case the "open" operation. After performing the desired operation, it returns to the calling function. It does not wait till the batch file commands have finished running.
Executing the batch file using the system function did not work because the system function did not return to the calling function ( main )while the batch commands are running.

This article has been dead for over six months. Start a new discussion instead.