views:

2079

answers:

8

Is it possible to make an application in C# that will be able to delete itself in some condition.

I need to write an updater for my application but I don't want the executable to be left after the update process.

There is an official .Net OneClick but due to some incompatibilities with my HTTP server and some problems of OneClick itself I'm forced to make one myself.

George.

[EDIT] In more details:

I have: Application Executable which downloads the updater ("patch", but not exactly) this "patch" updates the application executable itself.

Application executes as folowed:

Application: Start -> Check Version -> Download new Updater -> Start Updater -> exit;
Updater: Start -> do it's work -> start Application Executable -> self delete (this is where I get stuck);
A: 

Mhh so let me get this straight. You got some application.exe and your updater application updater.exe?

So when you start your application.exe it checks some webserver for a newer version and then starts updater.exe. And you want updater.exe to delete itself after it has finished updating? Or do you want to delete the downloaded patch (or similar)? Please be a bit more precise.

Consider that when you are deleting updater.exe you must recreate it for the next update process.

chrischu
I've added the application routine for precision.
George
+6  A: 

Hi, a quick google and I discovered this article.

Basically if you use Process.Start you can pass in the "Del" parameter and the path to the application you wish to delete.

James
Thanks for the article. Dunno why I couldn't find it :S
George
A: 

AppLife Update is an awesome product. It can even be used as a windows service running with administrative privileges to allow a limited user to update the application.

erikkallen
A: 

your second line can be

Updater: Star -> do it's work -> start Application Executable -> Updater Exits -> Application deletes your Updater.exe
I thought of that, but I need updater to delete itself.
George
Interesting. You are struggling with the solution that doesn't seem to work. What is the problem? WHY do you want updater to delete itself and why not the application?
+1  A: 

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] -> ...

Eamon Nerbonne
+2  A: 

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.

Mark Brackett
+2  A: 

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()
 {
  .....
 }
}
Emre Aydinceren
+2  A: 

Let me start by saying we offer a complete updating solution which includes:

wyUpdate handles all of the Vista/Windows 7 UAC problems and all the file permission problems that inevitably pop up when you're trying to update complex software.

That being said, if you want to build your own updater here are some tips:

Building your updater

A good place to start is the wyUpdate C# source code I mentioned above. You can cannibalize it and use it for your own purposes. Some of the algorithms it contains:

  • Full Windows Vista / Windows 7 UAC support
  • Ability for limited users to check and then update if they have credentials
  • Support for wonky corporate inernet. (If you've ever worked with a corporation this is a real problem).
  • Quick extracting, patching, and installing of files.
  • Registry support.
  • Roll back files & registry on error or cancellation by the user
  • Self-update (no files left behind)

We also have the file specifications here.

Automatic updating

Since being automatic is a requirement let me tell you how we do it with our AutomaticUpdater control.

We use named pipes to communicate between the standalone updater (wyUpdate) and the Automatic Updater control sitting on your program's form. wyUpdate reports progress to the Automatic Updater, and the Automatic Updater can tell wyUpdate to cancel progress, to start downloading, start extracting, etc.

This keeps the updater separate from your application.

In fact, the exact named pipes C# code we use is included in an article I wrote a little while back: Multi-process C# app like Google Chrome.

Wyatt O'Day