It's protected by system when an EXE is runing so we can't delete it. But the program can delete itself in an indirect way.
First the program should know whether it is a original one or cloned one:
If it is an original one it will clone itself to a temp folder and pass the needed parameters to this new one. The new cloned EXE file should be defined as FILE_FLAG_DELETE_ON_CLOSE . Then the original one ends itself.
If it is an cloned one it will synchronize original program with the parameters inputted. The original program will be deleted after it exited. Then this cloned one exits and be deleted by system as a temp file.
You can refer to the program written by Jeffrey Richter:
DeleteMe.CPP
Module name: DeleteMe.cpp
Written by: Jeffrey Richter
Description: Allows an EXEcutable file to delete itself
************************/
#include
#include
#include
/////////////////////////
int WINAPI WinMain(HINSTANCE h HINSTANCE b LPSTR psz int n) {
// Is this the Original EXE or the clone EXE?
// If the command-line 1 argument this is the Original EXE
// If the command-line >1 argument this is the clone EXE
if (__argc 1) {
// Original EXE: Spawn clone EXE to delete this EXE
// Copy this EXEcutable image into the user's temp directory
TCHAR szPathOrig[_MAX_PATH] szPathClone[_MAX_PATH];
GetModuleFileName(NULL szPathOrig _MAX_PATH);
GetTempPath(_MAX_PATH szPathClone);
GetTempFileName(szPathClone __TEXT( Del ) 0 szPathClone);
CopyFile(szPathOrig szPathClone FALSE);
// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
HANDLE hfile CreateFile(szPathClone 0 FILE_SHARE_READ NULL OPEN_EXISTI
NG FILE_FLAG_DELETE_ON_CLOSE NULL);
// Spawn the clone EXE passing it our EXE's process handle
// and the full path name to the Original EXE file.
TCHAR szCmdLine[512];
HANDLE hProcessOrig OpenProcess(SYNCHRONIZE TRUE GetCurrentProcessId());
wsprintf(szCmdLine __TEXT( s d \ s\ ) szPathClone hProcessOrig szPat
hOrig);
STARTUPINFO si;
ZeroMemory(&si sizeof(si));
si.cb sizeof(si);
PROCESS_INFORMATION pi;
CreateProcess(NULL szCmdLine NULL NULL TRUE 0 NULL NULL &si &pi);
CloseHandle(hProcessOrig);
CloseHandle(hfile);
// This original process can now terminate.
}
else {
// Clone EXE: When original EXE terminates delete it
HANDLE hProcessOrig (HANDLE) _ttoi(__targv[1]);
WaitForSingleObject(hProcessOrig INFINITE);
CloseHandle(hProcessOrig);
DeleteFile(__targv[2]);
// Insert code here to remove the subdirectory too (if desired).
// The system will delete the clone EXE automatically
// because it was opened with FILE_FLAG_DELETE_ON_CLOSE
}
return(0);
}