Single exe that can update itself?

For a while now, I’ve been meaning to make a diagnostic application for my coworkers while they are on the road so that we in IT can see what’s going on in their computers. But the problem has been getting the time to make it and deciding what best way to make it in (compiled or scripted). Eventually I chose a compiled solution as it would keep everything in one nice package without much if any outside dependancies.

However, I still needed a way for the application to get updated when I finished another version. I couldn’t rely on the users to check if they had the newest version since they could care less as long as it worked. I also didn’t want to put a lot of work into a distribution system specifically for an application that was a beta and not everyone needed even when it was completed. This meant that I needed to have the whole distribution/upgrade structure contained in one file that everyone was going to be running.

Roadblock, I found out that an application can’t overwrite its own file while its running. It makes sense for that to happen, but it makes it harder to upgrade yourself when it’s only you.

So how did I do this? Well since the newest version will be placed on a network folder, I figured that when the application finds a newer version, it will run the network copy and that instance will do the need upgrades. This presented a challenge though since I had to somehow create a version that could update itself before I could make a version that could update itself. Quite a chicken and egg conundrum!

What I ended up doing was create several different version of the exe and testing the upgrade code in chunks. Testing part of it here and there, constantly changing between the main app functionality and the upgrade code. #if and #endif preprocessor directives and different compile profiles came in really handy in defining different things depending on if I was running the upgrade or regular portions.

Well enough chitchat, time for code, which hopefully for those who program, should be understandable.

//method definition
//static void Main(string[] args)

//Look through the command line arguments and set some stuff up.
//Update the exe arguments.
hargs.Add("update", Array.Find(args, (delegate(string s) { if (s.ToLower() == "-update") { return true; } return false; })));
if (hargs["update"] != null && args.Length > 1)
{
	hargs.Add("update_path", args[Array.FindIndex(args, (delegate(string s) { if (s.ToLower() == "-update") { return true; } return false; })) + 1]);
}

//Updating executable?
if (hargs["update"] != null && hargs["update_path"] != null)
{
	//Make sure we know that it exists!
	if(System.IO.File.Exists(hargs["update_path"].ToString())) {
		System.IO.File.Copy(Application.ExecutablePath, hargs["update_path"].ToString(), true);

		//Start it up and exit this bitch!
		System.Diagnostics.Process.Start(hargs["update_path"].ToString());
	}
	return;
}
else
{
	if(System.IO.File.Exists(network_exe_path))
	{
		System.Diagnostics.FileVersionInfo newversion = System.Diagnostics.FileVersionInfo.GetVersionInfo(network_exe_path);
		if (newversion.FileVersion.CompareTo(Application.ProductVersion) > 0)
		{
			DialogResult dr = MessageBox.Show("There is a new version available. Download now?", "Update available", MessageBoxButtons.YesNo);
			if (dr == DialogResult.Yes)
			{
				System.Diagnostics.Process.Start(network_exe_path, "-update " + Application.ExecutablePath);
				return;
			}
		}
	}
}

“network_exe_path” is the network copy of the file and points to a UNC path (\\server\folder\app.exe). As you can see, this code doesn’t care what the local copy is named and will updated it regardless.

You can leave a response, or trackback from your own site.

One Response to “Single exe that can update itself?”

  1. [...] getting a Windows XP Virtual PC up and running I was able to test my last project’s update feature in XP…and it didn’t work. From those of you who have Vista like me know that the [...]

Leave a Reply