After the last few releases of applications I’ve been creating for my client it became apparent that we were in need of a more automated process that could guarantee that each employee using the software was aware of, and was made to upgrade to the latest version. This came after a relatively small change to the program to pull more data from a database than trying to dynamically determine the information from disconnected data. The systems around here are a bit on the rustic side of the technology spectrum.
Anyway, we’re using Framework 1.1 and desktop deployments are not as user friendly as the ClickOnce of Framework 2.0. There are still the manual processes, and the limitations of not having proper system/network access being a lowly consultant. So, I decided I would write an auto-updating plug-in for the applications, but first I’d check to see what others have done in order to save myself time.
That’s when I came across an article by Peter A. Bromber, Ph.D., that addressed building a Framework 1.1 Automatic Application MSI Updater. Pretty swanky, so I decided I’d take a look at his code as obviously he’s run into problems similar to my own. After digesting everything that he had to offer my mouth was left with an unsatisfying flavor of, well, I could do better to say for short.
Article for reference: http://www.eggheadcafe.com/articles/20060213.asp
Seeing that I could not use a webservice, since I’m not allowed to access the main servers, I was left with a less dynamic alternative. I would just have to use the App.Config file to point my application to an Access database, don’t ask. The access database I’d model similar to Dr. Brombers, but with better column names.
I then crafted my own implementation of his code, I noticed early on his recursive lookup for the assembly version was pointless, and also decided to create a typed dataset to return my data values. So I present to you my own implementation, in the works, of the Framework 1.1 Auto-Updater. Of course it’s still in the works as I’m not particularly fond of the fact that while the new installer is running, if you’re installing into the same file directory the running application can not complete until the old application is closed. You are forced to hit the ‘continue’ button twice in order to force the installer to overwrite the running application who spawned the installer via a new process. Anyway, here is my updated code:
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using ClientName;
namespace ClientName
{
/// <summary>
///
/// </summary>
public class AutoUpdater
{
private static OleDbConnection connUpgrade;
/// <summary>
/// Opens the Upgrade databases OLE DB connection.
/// </summary>
private static void OpenDbConnection()
{
string connString = string.Empty;
try
{
connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ConfigurationSettings.AppSettings.Get("UpgradeDbPath");
connUpgrade = new OleDbConnection(connString);
connUpgrade.Open();
}
catch(Exception err)
{
CloseDbConnection();
}
}
/// <summary>
/// Closes the Upgrade databases OLE DB connection.
/// </summary>
private static void CloseDbConnection()
{
if(connUpgrade != null)
{
if(connUpgrade.State != ConnectionState.Closed)
{
connUpgrade.Close();
connUpgrade.Dispose();
connUpgrade = null;
}
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool CheckForUpdate()
{
bool result = false;
string appName = string.Empty;
string lastVersion = string.Empty;
string currentVersion = string.Empty;
string appExeName = string.Empty;
UpdateDataset.AppVersionsRow appRow = null;
try
{
// Get the current assemblies Product Name
appName = Assembly.GetEntryAssembly().GetName().Name;
appRow = GetAppVersionInfo(appName);
if(appRow != null)
{
lastVersion = Application.ProductVersion;
if (appRow.CurrentVersion != lastVersion)
{
UpdateForm frmUpdate = new UpdateForm();
frmUpdate.BringToFront();
frmUpdate.StartPosition = FormStartPosition.CenterScreen;
DialogResult dlgResult = frmUpdate.ShowDialog();
if (frmUpdate.UserAccept == true)
{
Process proc = new Process();
proc.StartInfo.FileName = appRow.AppExeName;
proc.StartInfo.WorkingDirectory = appRow.InstallerPath;
proc.Start();
proc.WaitForExit();
Process.Start(Application.ExecutablePath);
Environment.Exit(0);
}
else if (dlgResult == DialogResult.Cancel)
{
result = false;
}
}
}
}
catch(Exception err)
{
Environment.Exit(0);
}
return result;
}
/// <summary>
/// Gets the Application Version record for the supplied
/// application product name.
/// </summary>
/// <param name="appName"></param>
/// <returns></returns>
private static UpdateDataset.AppVersionsRow GetAppVersionInfo(string appName)
{
string sqlSelect = string.Empty;
UpdateDataset dsUpdate = null;
OleDbDataAdapter adapter = null;
OleDbParameter param = null;
UpdateDataset.AppVersionsRow appRow = null;
try
{
dsUpdate = new UpdateDataset();
sqlSelect = @"SELECT AppName, AppExeName, InstallerPath, CurrentVersion FROM AppVersions WHERE AppName = @appName";
OpenDbConnection();
adapter = new OleDbDataAdapter(sqlSelect, connUpgrade);
param = new OleDbParameter("@appName", OleDbType.VarChar);
param.Value = appName;
adapter.SelectCommand.Parameters.Add(param);
adapter.Fill(dsUpdate.AppVersions);
CloseDbConnection();
appRow = dsUpdate.AppVersions.FindByAppName(appName);
}
catch(Exception err)
{
string message = err.Message;
}
finally
{
CloseDbConnection();
}
return appRow;
}
}
}
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5