Self deletable application in C# in one executable
If you use Process.Start you can pass in the Del
parameter and the path to the application you wish to delete.
ProcessStartInfo Info=new ProcessStartInfo();
Info.Arguments="/C choice /C Y /N /D Y /T 3 & Del "+
Application.ExecutablePath;
Info.WindowStyle=ProcessWindowStyle.Hidden;
Info.CreateNoWindow=true;
Info.FileName="cmd.exe";
Process.Start(Info);
Code snippet taken from this article
I suggest you use a batch file as a bootstrap and have it delete itself and the exe afterwards
public static class Updater
{
public static void Main()
{
string path = @"updater.bat";
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("updater.exe");
sw.WriteLine("delete updater.exe /y");
sw.WriteLine("delete updater.bat /y");
}
System.Process.Start(path);
}
else
{
RunUpdateProcess();
}
}
private void RunUpdateProcess()
{
.....
}
}
It's tricky without introducing yet another process (that you'd then want to delete as well, no doubt). In your case, you already have 2 processes - updater.exe and application.exe. I'd probably just have the Application delete updater.exe when it's spawned from there - you could use a simple command line arg, or an IPC call from updater.exe to application.exe to trigger it. That's not exactly a self deleting EXE, but fulfills the requirements I think.
For the full treatment, and other options you should read the definitive treatment of self deleting EXEs. Code samples are in C (or ASM), but should be p/invokable.
I'd probably try CreateFile with FILE_FLAG_DELETE_ON_CLOSE
for updater.exe with something like (psuedo code):
var h = CreateFile(
"updater.exe",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE
);
byte[] updaterBytes = GetUpdaterBytesFromWeb();
File.WriteAllBytes("updater.exe", updaterBytes);
Process.Start("updater.exe");
Once application.exe exits, updater.exe has a file handle of 1. When updater.exe exits, it drops to 0 and should be deleted.
Couldn't you simply delete the updater from within the application? i.e.:
Application: Start -> [Delete old updater if present] -> Check version -> Download new updater -> Start updater -> exit;
Updater: Start -> Perform update -> Start application -> exit;
Application: Start -> [Delete old updater if present] -> ...