Updating the software to customers every time manually is gruesome task.This consumes lots of time of effort.
Example consider , releasing a new version within short span of time, or installing it to large no of customers really tough right.
Here i share a simple way of updating the software Automatically.
The main idea behind Auto-updating the software is,
- Provide a way to track the latest update available , this can be achieved through updating the version in a Settings file or DB. In this example am using a settings file.
- Replacing the setup with a newer version.This can be done in 2 ways.
- Probably the easiest one, Set the DetectNewInstalledVersion and ReplacePreviousVersions property in visual studio to true.
- Using WMI to read all the software's installed then uninstall the previous version of the application being upgraded. The code is explained below. Note: Add a reference to System.Management object.
- Installing the new version ,
First step in creating this application is hosting the settings file.
The best place would be in a server accessible to all the users.
Assuming that u have hosted the settings file in your server "http://myserver/" ,
For the first time , the application has to be installed manually, later on for the next updates setup files can be placed in the server.
lets continue with Coding part.
For the first time , the application has to be installed manually, later on for the next updates setup files can be placed in the server.
lets continue with Coding part.
Creating a form
The form basically consists of 2 labels , progressbar , button and a backgroundworker.
Dwelling into the functionality.
The Application mainly consists of the following functions.
- private void Form1_Load(object sender, EventArgs e).
- private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
- private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
- private void btnupdate_Click(object sender, EventArgs e)
- public void CheckUpdate()
- private bool installupdates()
- private void unisntall()
- private void downloadFiles(string filename)
Lets understand the functions more clearly.
1. FORM LOAD event.
In the form load event , just display the product version.
private void Form1_Load(object sender, EventArgs e)
{
lblversion.Text = this.ProductVersion;
}
{
lblversion.Text = this.ProductVersion;
}
2. ButtonClick event.
This this we trigger the background job to start.
private void btnupdate_Click(object sender, EventArgs e)
{
if(!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
}
{
if(!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
}
3. Backgroundworker_Dowork event.
Here we call the CheckUpdate() to perform the update tasks.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if(!backgroundWorker1.IsBusy)
CheckUpdate();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if(!backgroundWorker1.IsBusy)
CheckUpdate();
}
4. Checkupdate function
performs the update tasks.
/// <summary>
/// performs the update tasks
/// </summary>
public void CheckUpdate()
{
/// gets the product current version.
version = new Version(this.ProductVersion);
DataSet ds = new DataSet();
try
{
/// downloads the settings file containing the version information from the server.
downloadFiles("version.xml");
ds.ReadXml(@"D:\test\version.xml");
backgroundWorker1.ReportProgress(40);
foreach (DataRow row in ds.Tables[0].Rows)
{
/// compares the product version and the latest version available from the server.
if (version.CompareTo(new Version(row[0].ToString())) < 0)
{
///update available.
///downloads the updates(setup file).
backgroundWorker1.ReportProgress(70);
downloadFiles("application_name.msi");
//installs the updates.
isInstalled=installupdates();
if (isInstalled)
{
backgroundWorker1.ReportProgress(100);
///if u plan to uninstall manually, call this function
///currently not called.
// unisntall();
}
else
///report error.
backgroundWorker1.ReportProgress(-1);
return;
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
backgroundWorker1.ReportProgress(-1);
return;
}
/// performs the update tasks
/// </summary>
public void CheckUpdate()
{
/// gets the product current version.
version = new Version(this.ProductVersion);
DataSet ds = new DataSet();
try
{
/// downloads the settings file containing the version information from the server.
downloadFiles("version.xml");
ds.ReadXml(@"D:\test\version.xml");
backgroundWorker1.ReportProgress(40);
foreach (DataRow row in ds.Tables[0].Rows)
{
/// compares the product version and the latest version available from the server.
if (version.CompareTo(new Version(row[0].ToString())) < 0)
{
///update available.
///downloads the updates(setup file).
backgroundWorker1.ReportProgress(70);
downloadFiles("application_name.msi");
//installs the updates.
isInstalled=installupdates();
if (isInstalled)
{
backgroundWorker1.ReportProgress(100);
///if u plan to uninstall manually, call this function
///currently not called.
// unisntall();
}
else
///report error.
backgroundWorker1.ReportProgress(-1);
return;
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
backgroundWorker1.ReportProgress(-1);
return;
}
backgroundWorker1.ReportProgress(99);
}
5.Backgroundworker progress changed event
/// <summary>
/// Updates the progress bar and status of the operations.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
switch (e.ProgressPercentage)
{
case 40: lblstatus.Text = "Checking for updates...";
progressBar1.Value = e.ProgressPercentage;
break;
case 70: lblstatus.Text = "Downloading necessary components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 80: lblstatus.Text = "Installing components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 90: lblstatus.Text = "Removing previous components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 100: lblstatus.Text = "completing Installation";
progressBar1.Value = e.ProgressPercentage;
this.Hide();
MessageBox.Show("Restart the application for the changes to take effect.","Restart");
this.Close();
break;
case 99: lblstatus.Text = "";
progressBar1.Value = 100;
this.Hide();
MessageBox.Show("Product is upto date");
this.Close();
break;
default: lblstatus.Text = "update failed";
this.Hide();
MessageBox.Show("Update failed");
this.Close();
break;
}
}
/// Updates the progress bar and status of the operations.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
switch (e.ProgressPercentage)
{
case 40: lblstatus.Text = "Checking for updates...";
progressBar1.Value = e.ProgressPercentage;
break;
case 70: lblstatus.Text = "Downloading necessary components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 80: lblstatus.Text = "Installing components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 90: lblstatus.Text = "Removing previous components...";
progressBar1.Value = e.ProgressPercentage;
break;
case 100: lblstatus.Text = "completing Installation";
progressBar1.Value = e.ProgressPercentage;
this.Hide();
MessageBox.Show("Restart the application for the changes to take effect.","Restart");
this.Close();
break;
case 99: lblstatus.Text = "";
progressBar1.Value = 100;
this.Hide();
MessageBox.Show("Product is upto date");
this.Close();
break;
default: lblstatus.Text = "update failed";
this.Hide();
MessageBox.Show("Update failed");
this.Close();
break;
}
}
6. InstallUpdates function
/// <summary>
/// Installs the new version of application
/// </summary>
/// <returns></returns>
private bool installupdates()
{
bool appInstalled = false;
backgroundWorker1.ReportProgress(80);
///creates a process to install the process.
Process p = new Process();
///Msi installer
p.StartInfo.FileName = "msiexec.exe";
///parameters to install the application.
/// /i = install
/// /qb = basic user interface
p.StartInfo.Arguments = "/i \"tempfolder\application_name.msi\"/qb";
p.Start();
//wait for process to complete
p.WaitForExit();
if (p.ExitCode == 0)
appInstalled = true;
return appInstalled;
}
/// Installs the new version of application
/// </summary>
/// <returns></returns>
private bool installupdates()
{
bool appInstalled = false;
backgroundWorker1.ReportProgress(80);
///creates a process to install the process.
Process p = new Process();
///Msi installer
p.StartInfo.FileName = "msiexec.exe";
///parameters to install the application.
/// /i = install
/// /qb = basic user interface
p.StartInfo.Arguments = "/i \"tempfolder\application_name.msi\"/qb";
p.Start();
//wait for process to complete
p.WaitForExit();
if (p.ExitCode == 0)
appInstalled = true;
return appInstalled;
}
6. unistall function
uninstalls the previous version of the application
private void unisntall()
{
///selects all installed products
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
ManagementObjectCollection moReturn = mos.Get();
foreach (ManagementObject mo in moReturn)
{
///checks for the application name and version
if (mo["name"].ToString() == "setup_name" && version.CompareTo(new Version(mo["version"].ToString())) == 0)
{
backgroundWorker1.ReportProgress(90);
//uninstalls the application
mo.InvokeMethod("UNINSTALL", null);
backgroundWorker1.ReportProgress(100);
return;
}
else
continue;
}
}
{
///selects all installed products
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
ManagementObjectCollection moReturn = mos.Get();
foreach (ManagementObject mo in moReturn)
{
///checks for the application name and version
if (mo["name"].ToString() == "setup_name" && version.CompareTo(new Version(mo["version"].ToString())) == 0)
{
backgroundWorker1.ReportProgress(90);
//uninstalls the application
mo.InvokeMethod("UNINSTALL", null);
backgroundWorker1.ReportProgress(100);
return;
}
else
continue;
}
}
8. Downloadfile function
Downloads the files from the server , "http://myserver/".
private void downloadFiles(string filename)
{
try
{
System.Net.WebClient webclient = new System.Net.WebClient();
webclient.DownloadFile("http://myserver/" + filename, "tempfolder" + filename);
}
}
{
try
{
System.Net.WebClient webclient = new System.Net.WebClient();
webclient.DownloadFile("http://myserver/" + filename, "tempfolder" + filename);
}
}
Last step , Creating a setup project.
Follow the steps below.