views:

1871

answers:

11

For technical reasons, I can't use ClickOnce to auto-update my .NET application and its assemblies. What is the best way to handle auto-updating in .NET?

+9  A: 

I think the Updater Application Block was something of a precursor to ClickOnce. Might be worth investigating. Looking at its source code might be enough to spark some ideas.

Matt Hamilton
Thanks! This was what I remembered reading a couple of years ago.
MusiGenesis
And now I'm remembering why I never ended up using it. Sheesh.
MusiGenesis
lol! Yeah the Application Blocks are a bit daunting. I've never used them either.
Matt Hamilton
"This setup requires the .NET Framework version 1.1.4322..." jeez this thing is old.
Cameron MacFarland
Updater Application Block is a retired project as seen at http://msdn.microsoft.com/en-us/library/ms978574.aspx
Junior Mayhé
+1  A: 

Write your own.

I have heard that they are somewhat difficult to write the first time, but after that it gets simple.

Since I haven't written one yet (although its on my list), I can give you some of the things that I have thought of. Maintain accurate dll versions, as this is important for self updating. And make sure that the updater can update itself.

MagicKat
Doing that is really fun! I did it by letting the application update the updater.
Vincent McNabb
Rolling my own updater took several months at my company but now we have one we know inside and out and can debug at will. It was truly worth it.
Dinah
+1  A: 

In your Program.cs file do something like this:

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Update();
        Application.Run(new Form1());
    }

    private static void Update()
    {
        string mainFolder;
        string updateFolder;
        string backupFolder;

        foreach (string file in
            System.IO.Directory.GetFiles(updateFolder))
        {
            string newFile = file.Replace(
                updateFolder, mainFolder);

            if (System.IO.File.Exists(newFile))
            {
                System.IO.File.Replace(file, newFile, backupFolder);
            }
            else
            {
                System.IO.File.Move(file, newFile);
            }
        }
    }

Additionally, it can be made recursive to pick up directory structure if necessary. This will allow you to update any .dll in your project; everything, in fact, outside of the main .exe. Then somewhere else within your application you can deal with getting the files from your server (or wherever) that need to be updated, put then in the updateFolder and restart the application.

Timothy Carter
Thanks. Mainly I was directing the question at self-updating (i.e. updating the main EXE from within the main EXE).
MusiGenesis
You can't update the exe, from the exe itself though, so you still have to have an outside process.
Mitchel Sellers
Sure you can. You have your exe rename itself, queue a "delete after restart" command on the old version and copy in the new version. The old app can then run the new app and exit immediately afterwards, possibly passing some sort of /upgrade parameter, so the new app knows that potentially old stored data structures need to be updated.
Sander
+2  A: 

About 3-4 years ago I published an example that sits outside the app, if an update is detected, the app calls the updater ans shuts down, then the updates are done, and the app restarts.

I published the example on the old GotDotNet site...I'll have to try and find it.

It worked perfect and took about 1-2 hours to write.

Mitchel Sellers
How do you update the updater?
MusiGenesis
I have a method inside the app, that if an update is found for the updater it will apply that update. Basically each updates the other, it sounds complex and hard to manage but is actually very simple. I think at minimum I still have the code at home somewhere.
Mitchel Sellers
Could you publish it?
pn
I'm still trying to find the sample code. It was published on an old Microsoft site....and they shut down the site and samples....
Mitchel Sellers
+2  A: 

Indigo Rose has a product called TrueUpdate that also does this for you. I have used them in the past from both managed and unmanaged apps. It is basically a file you put on your server (http, ftp, whatever you like). Then you call a client side EXE to check for updates. The updates file is pulled and has logic to detect what version is on the client (your choice, DLL detection, registry key reads, etc). Then it will find the appropriate updater for it and download the file for execution. It works well through proxies as well.

The only thing they don't do is actually build the patches for you. You have to do that manually, or with another product they have. It is a commcerial solution and works quite well though if you need it.

Jason Short
Looks cool, thanks, but no Windows Mobile support. This app is a little unusual in that it runs in both Windows Mobile and regular PC Windows.
MusiGenesis
+1  A: 

On a project a long time ago, using .NET Compact Framework 1.0, I wrote an auto-updating application. We used SqlCE's CAB deployment feature to get the files onto the device (you would use Sync Framework now), and we had a separate exe that did the unpacking of the CAB, and updating the files.

An update would go like this: the user would be prompted to update, click a button and drop out of the UI application. The updater exe would take over, get the cab file from the server, backup the current dlls and unpack the cab file with wceload. The UI would then be restarted, and if it failed, the update would be rolled back. This is still an interesting scenario on compact devices, but there are better tools now than just sqlce.

I would certainly look at updater application block and sync framework to implement this if clickonce is not an option. But I'm guessing you'll still need a separate executable because the dlls you want to overwrite are probably file locked while in use by an exe, like one of the previous answers already said.

StephaneT
How do you get the updater exe to take over after the UI closes? Is it always running and polling to see if an update is required? I've tried automatically starting the updater in another process, but I'm still unable to overwrite the original running EXE.
MusiGenesis
I don't remember exactly, but you could do this with a manualresetevent or a semaphor-like mechanism. As a last action, the exiting UI triggers a system-wide event. By the time the updater downloaded the CAB, unpacked it and tries to overwrite the UI exe, it has long since exited.
StephaneT
A: 

How about WiX?

Kevin Fairchild
+1  A: 

As a starting point for rolling your own, it's probably worth looking at Alex Feinman's article on MSDN entitled "Creating Self-Updating Applications with the .NET Compact Framework".

ctacke
+1  A: 

I wrote my own autoupdater, the autoupdater uses a common config file to the application which contains urls to download latest versions from / check if it needs to update.

This way you run the updater, which either updates the app or not, then runs the application, which as part of normal operation, checks for an updated updater and patches that.

TreeUK
+3  A: 

We have a product that's commercial/open source: wyBuild & wyUpdate. It has patching ability and is dead simple to use.

Edit: I'm getting voted down into the negative numbers, but my post wasn't just blatant selling. Our updater, wyUpdate, is open source, written in C# and is licensed under the BSD license.

I thought it might help anyone trying to build an updater from scratch using the .NET framework.

But, vote me down if you must.

Wyatt O'Day
How is this in any way helpful to a Compact Framework deployment?
ctacke
Our open source updater might be very helpful when developing your own updater. It's written in C# and licensed under the BSD license. But vote me down if you must.
Wyatt O'Day
+1  A: 

Hi,

I want to recommend you BitsUpdater. It is simple and extendable library for automatic update process using BITS (technology used by Windows Update).

There is a sample for processes (special project called ApplicationLauncher) and you can extend library with your own solution for updating any other services (database, ...).

jakubgarfield