A few years ago, while programming in Delphi, I personally built for myself some kind of automatic update code, which later became indispensable when developing any program that has an update. At the moment this code is completely rewritten in c # and I want to share it with you.

First we define the goals of this implementation:
- When a new version is detected, the update should occur automatically;
- After the update, the program should automatically restart;
- After updating the program name should remain the same.
The problem is that the program cannot delete, replace and restart itself. And, it would seem, how to solve this issue? Here we will be helped by the second file, which is responsible for renaming and restarting the program, since we do not pursue the goal of storing all codes in 1 file.
')
Stages
Stage 1: Version Verification
Due to my laziness to look for the best option, 2 files were posted on the site:
Yes, it is the XML format that I use. Running off-topic I will say that in the version.xml file I have a list of several versions of files, but we will consider only one.
Go ahead. The structure of the version file is as follows:
<version> <myprogram>1.0.2.37</myprogram> </version>
A backgroundWorker component has been added to the form (to implement background file loading) with the following code inside the DoWork handler:
try { double versionRemote = Convert.ToDouble(doc.GetElementsByTagName("myprogram")[0].InnerText.Replace(".", "")), thisVersion = Convert.ToDouble(Application.ProductVersion.Replace(".", "")); if (thisVersion < versionRemote) { MessageBox.Show(this, " (" + doc.GetElementsByTagName("myprogram")[0].InnerText + ")" + Environment.NewLine + " .", Application.ProductName + " v" + Application.ProductVersion, MessageBoxButtons.OK, MessageBoxIcon.Information); var client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(download_ProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(download_Completed); client.DownloadFileAsync(new Uri(@"http://mysite/myprogram.exe"), "temp_myprogram"); } } catch (Exception) { }
What we see in the code above:
Since the version we can have a large number, we use the variable type double. To compare versions, we delete all points and convert the version from a string to a number (in the example, the number is 10237).
We will do the same with the version of the file itself assigned to the variable
thisVersion .
After that we need to compare the local version with the remote one, and if our version is smaller than the remote one, then we first display a message informing about the further update. After that, the program starts downloading the file to the same folder from which it is running. The file is named
temp_myprogram .
To track the download status, a progressBar component was added to the form, and a function was added to the code:
private void download_ProgressChanged(object sender, DownloadProgressChangedEventArgs e) { try { progressBar1.Value = e.ProgressPercentage; } catch (Exception) { } }
The function displays the file download status in the progress bar. This is only for visual display.
So, we downloaded our file and what to do next? And then the
download_Completed function comes into
play , containing the code:
private void download_Completed(object sender, AsyncCompletedEventArgs e) { try { Process.Start("updater.exe", "temp_myprogram myprogram.exe"); Process.GetCurrentProcess().Kill(); } catch (Exception) { } }
Everything is simple here: run the
updater.exe file with the parameters, which I will discuss in the next step.
The second line indicates the need to force the application to shut down.
Stage 2: Update Processing
Next, the
updater.exe utility comes to the rescue, a functional feature of which is to check the shutdown of the main application and update processing.
Well, let's not go into the text and go straight to the code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Threading; namespace Updater { class Program { static void Main(string[] args) { try { string process = args[1].Replace(".exe", ""); Console.WriteLine("Terminate process!"); while (Process.GetProcessesByName(process).Length > 0) { Process[] myProcesses2 = Process.GetProcessesByName(process); for (int i = 1; i < myProcesses2.Length; i++) { myProcesses2[i].Kill(); } Thread.Sleep(300); } if(File.Exits(args[1])){ File.Delete(args[1]); } File.Move(args[1], args[0]); Console.WriteLine("Starting "+args[1]); Process.Start(args[1]); } catch (Exception) { } } } }
Since we do not need forms, the project is assembled as a regular console application, whose actions are quite simple.
We set a cycle that checks whether the process specified in the 2nd parameter is running. If the process is found, then the
Kill () command will be transferred to it for a forced end, after which we wait 300 milliseconds and repeat. The cycle will work until the process is complete.
Next, delete the old file. To eliminate some errors (rather errors in the brain), we add the function of checking the existence of a file.
After deleting, rename the name of the file specified in the 1st parameter to the name specified in the 2nd parameter. In our case, the
temp_myprogram file will be renamed to
myprogram.exe , after which the
myprogram.exe process will be launched and the window of this update will be closed.
I also want to say that the updater file I use in all my projects where it is required, since it does not have a binding to any particular application.
And go to the next step:
Stage 3: Completion
And here we see that the updated version file was successfully launched, and the "update" window was closed. Profit!
The article is written on the basis of the launcher for modpak "PROTanki" to the game "World of Tanks" with the original screenshots of the application. For those who say āthis functionality is not thereā, Iāll immediately say that this launcher is in beta test and is available to a limited number of people.
If anyone needs the
updater.exe file, you can always download its current version
HERE , on my official website. Currently the current version is
1.0.0.2 .
And on this line, our automatic update code comes to an end.
UPD. I wrote the second article containing part of the amendments.
We kindly ask, who else has thoughts about āhand curvesā, ācurve codeā, etc., write at least in the comments what is wrong. Based on your constructive criticism, I will improve my work, thereby learning how to write better code.
Thanks in advance!Sincerely, Andrei Helldar!