Creating an automated update service

Many applications on the mobile device today come with tools that let the user download patches or latest updates from a remote server (when an Internet connection is available) and directly install them on the mobile device. This can help to take the load of maintenance and upkeep of the mobile application off the systems administrator. An automated update service ensures that mobile end users can freely apply patches and updates to their mobile device at the click of a button.

Your application should be no different. In a nutshell, this auto-update service will consist of two parts, one part being the server side and the other the mobile device side. At the server side, you will use web services. Your web service will do the following:

• Host the latest updates (in the form of CAB files)

• Provide a method that the mobile device code can call to retrieve information on the latest updates (such as version number, download size of the update, and so on)

At the mobile device side, your updater service should do the following:

1. Call the web service to retrieve information on the latest updates

2. Check the current version number of the application against the latest version number retrieved from the web service and decide whether an update is required

3. If an update is required, download the new CAB file and automatically deploy it

4. Update the application's current version number on the mobile device

Creating the server-side web service

We choose web services because it is relatively easy to set up and connect to. Create an ASP.NET web service project and name it salesForceAutoUpdateService. Add a new Web Service (.asmx) file to your project named Updateservice.asmx, and delete the automatically created Servicei.asmx file.

You will need to store information about the latest application updates somewhere on the server. Setting up a whole database for this seems like overkill, so the best way is to store it in an XML file. Add a new XML file (named SalesForceAppVersion.xml) to your project. The XML file only needs to store information about the latest version of the application. It is recommended to store at least the following details:

• Latest version number

• Latest version date

• Name of application

Write the following contents in the XML file:

<?xml version="1.0" encoding="utf-8" ?> <Applications>

<SalesForceApp UpdatesCabFile="" LatestVersion="2" VersionDate="12/Jan/2010" /> </Applications>

Every time you need to make a new version of the application available to all your mobile users, you will need to place a copy of the latest CAB file on your server and then update this XML file.

Now let's create a web method that reads from this XML file and returns the information to the calling program. Take note that this web method assumes that the CAB file containing the updates is stored in a folder named \updateFiles in your web service folder. The information about the latest updates is returned as a comma-separated string of values.


public string GetApplicationVersionInfo(string ApplicationName) {

//Load the XML file

XmlDocument _xml = new XmlDocument(); _xml.Load


+ "\\SalesForceAppVersion.xml");

//Retrieve the application node XmlNodeList _xmlNodeList =

_xml.GetElementsByTagName("Applications"); XmlElement _xmlAppRootNode =

(XmlElement)_xmlNodeList.Item(0); XmlNodeList _xmlAppNodeList =

_xmlAppRootNode.GetElementsByTagName (ApplicationName);

if (_xmlAppNodeList.Count == 0) return ""; XmlElement _xmlApplicationNode =


//Get the full path to the CAB file on the server String _cabFileName =

_xmlApplicationNode.GetAttribute("UpdatesCabFile"); String _cabFilePath =

AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\UpdateFiles\\" + _cabFileName;

//Calculate the filesize of the CAB file

Filelnfo _file = new FileInfo(_cabFilePath); String _packageSizeInBytes =


//Place all the details in a comma-separated string and //return this string _data +=

_xmlApplicationNode.GetAttribute("LatestVersion") + "," + _packageSizeInBytes + "," +

_xmlApplicationNode.GetAttribute("VersionDate") + "," + _cabFileName; return _data;

catch (Exception) {

return "";

That's all you need for the web service. Your next step is to place a dummy .cab file in the <webservicefolder>\updateFiles folder. Copy the CAB file you've created earlier into the UpdateFiles folder. Rename this CAB file

Register this web service with IIS by creating a virtual folder that points to this web service. Test your web service by navigating to the following URL in any browser on your PC.


You should be able to see your web service and its list of methods show up in your browser. You can even test out your web method. Click on the GetApplicationVersionInfo link, key in SalesForceApp as the Application argument, and click the Invoke button. You will see the following data returned:

fr http://edzehoo-pc/SaiesForceAutoUpdateService/UpdateService.asmVGet^pplicatianVersionInfo - Inter... | 1=1

rxr\ WW

fr http://edzehoo-pc/SaiesForceAutoUpdateService/UpdateService.asmVGet^pplicatianVersionInfo - Inter... | 1=1

■jß . h ttp ; - - edzeh qq- p c/Sa 1 es F o rc eAi T



v; Favorites 'jQ Suggested Sites w


v; Favorites 'jQ Suggested Sites w

& httpi/Zedzehoo-pc/SaiesForceAutoUpdate...

<?xml version-'1.0" encoding="utf-8n ?> <s trin g xmlris-'>2f558569,12/Jan/2010,></stnng>


9 Internet | Protected Mode: Off

In the next section, you will learn how to create the client-side part of the equation.

Creating the client-side updater tool

The updater service at the client-side is a separate application with an interface that allows the user to trigger the update process. Create a new Smart Device Application project, and design the following form:

SalesForce Updater

This tool allows you to check and download the latest updates for the SalesForce application

Current version:

Check for Updates

Latest version: Version date: Download size:

The gray panel (pnlRemoteFiles) is initially invisible. When a user clicks the Check for Updates button, this will initiate a check against the web service on a remote server. It will check if the local copy of the application needs an update (by checking the local version number against the latest version number available from the web service). If an update is needed, the gray panel is shown (together with the details of the latest updates). The user can then download and install these updates by clicking the Download & install updates button. There is also a progress bar below this button that shows the file download progress.

You will also need a place to store the current application version on the mobile device. You can use an XML file for this purpose. Add a new XML file to your project and name it SalesForceAppDeviceVersion.xml. Write the following contents in this file:

<?xml version="1.0" encoding="utf-8" ?> <Applications>

SalesForceApp CurrentVersion="1" /> </Applications>

In your project, ensure that you set the Copy to Output Directory property to Copy always in the property window of the XML file (as shown below).

Properties t ^ X

SalesForceAppDeviceVerskjnjtml File Properties "

Build Action


Copy to Output Direct!

Custom Tool Custom Tool Namespc File Name SalesForceAppDeviceVersio

Full Path d:\BusinessVenturesBacku

As the updater service will need to connect to the remote web service on your PC, you need to add a web reference to the web service. Right-click on the project and click the Add Web Reference menu item. Key in the full URL to the web service in the pop-up window. Take note that this web service will be called from your mobile device, so you should avoid using localhost in the URL. Refer to the web service using the full machine name of your PC (shown in the next screenshot). Name this web reference AutoUpdater.

In your form, you first need to declare a few global variables to store version details:

using System.Net; using System.IO;

//Local version information private int _currentVersion;

//Remote version information private int _remoteVersionNo; private DateTime _remoteVersionDate; private string _updatesCabFile; private int _updatesCabFileSize;

In the load event of the form, you need to parse the XML file and retrieve the local version information.

public void Updater_Load(object sender, System.EventArgs e) {

//Get Local Version information LoadLocalVersion();

private void LoadLocalVersion() {

XmlDocument _xml = new XmlDocument();

_xml.Load(GetCurrentApplicationPath().TriniEnd("\\".ToCharAr ray()) + "\\SalesForceAppDeviceVersion.xml"); XmlNodeList _xmlNodeList =

_xml.GetElementsByTagName("Applications"); XmlElement _XmlAppRootNode = (System.Xml.XmlElement)

(_xmlNodeList.Item(0)); XmlNodeList _xmlAppNodeList =

_XmlAppRootNode.GetElementsByTagName("SalesForceApp"); XmlElement _xmlApplicationNode = (System.Xml.XmlElement)

(_xmlAppNodeList.Item(0)); _currentVersion = int.Parse(

_xmlApplicationNode.GetAttribute("CurrentVersion")); lblCurrentVersion.Text = _currentVersion.ToString();

In the click event of the Check for Updates button on your form, you need to call the web service, retrieve the latest version information, and then compare it against the local version information retrieved earlier. You can do this via the following code:

public void btnCheckUpdates_Click(System.Object sender,

System.EventArgs e)

AutoUpdater.UpdateService _service = new

AutoUpdater.UpdateService(); string _data; string[] _versionInfo;

//Call the web service _data =


//Since the returned data is a comma-separated string, we //split it into its constituent data fields

_versionInfo = _data.Split(','); _remoteVersionNo = int.Parse(_versionInfo[0]); _updatesCabFileSize = int.Parse(_versionInfo[1]); _remoteVersionDate = DateTime.Parse(_versionInfo[2]); _updatesCabFile = _versionInfo[3];

//Checks the version retrieved from the webservice against //the current version if (_remoteVersionNo > _currentVersion) {

//If a latest update is available, display its //details in the gray panel and make it visible lblLatestVersion.Text = _remoteVersionNo.ToString(); lblDownloadSize.Text =

String.Format("{0:0,0}",_updatesCabFileSize) + " bytes"; lblVersionDate.Text = _remoteVersionDate.ToString(); pnlRemoteFiles.Visible = true;

//If an update is not required, display a message MessageBox.Show("Your SalesForce application is already up to date");

When the user clicks the Download & install updates button, you will need to download the update CAB file from the remote server. You can programmatically download a file using the system.Net.HttpWebRequest class. Using this class consists of the following steps:

1. Call HttpWebRequest.Create(URL) to create a request object on the desired file specified by the URL

2. Call HttpWebRequest.GetResponse() to get a response object

3. CallWebResponse.GetResponseStream().BeginRead() and WebResponse. GetResponseStream().EndRead() repeatedly to download chunks of the file asynchronously

You first need to declare a few additional global variables for the web request.

//Variables used to download the updates CAB file private byte[] _downloadBuffer;

private int _downloadChunkSize = 6 5 53 6;

private int _totalBytesDownloaded = 0;

private FileStream _fileStreamObj;

private WebResponse _webResponse;

private HttpWebRequest _webRequest;

private string _localCabPath;

In the click event of the Download and install updates button, write the following code:

public void btnDownloadAndInstall_Click(System.Object sender,

System.EventArgs e)

_webRequest = (HttpWebRequest)

(HttpWebRequest.Create("http://edzehoo-pc/SalesForceAutoUpdateService/updatefiles/" + _updatesCabFile)); _webResponse = _webRequest.GetResponse();

//Initialize the download buffer. The download buffer //ideally should be a 64Kb chunk _totalBytesDownloaded = 0;

_downloadBuffer = new byte[_downloadChunkSize + 1];

//Initialize the progressbar pbDownload.Minimum = 0;

pbDownload.Maximum = _updatesCabFileSize; pbDownload.Value = 0;

//Initialize the File stream object that receives the file //data

_localCabPath =


+ "\\" + _updatesCabFile; _fileStreamObj = new FileStream(_localCabPath, FileMode.Create);

//Start the asynchronous file download - download the first //64Kb chunk

_webResponse.GetResponseStream().BeginRead(_downloadBuffer, 0, _downloadChunkSize, new AsyncCallback(DataReceived), this);

In the previous code, you are referencing an asynchronous callback function named DataReceived. This callback function is automatically invoked when the amount of data specified (via _downloadChunkSize) has been downloaded successfully. In this callback function, you retrieve the downloaded data, write it to the file stream object, update the progress bar, and then initiate another asynchronous read (of the next 64 KB chunk of data). This process repeats itself until there is no data left to read.

private void DataReceived(IAsyncResult Data) {

int _downloadedSize =


//Write the downloaded data into the file stream object _fileStreamObj.Write(_downloadBuffer, 0, _downloadedSize); _totalBytesDownloaded += _downloadedSize;

//Update the progress bar pbDownload.Invoke (new EventHandler (UpdateProgress)); //Check if all bytes downloaded if (_totalBytesDownloaded < _updatesCabFileSize) {

//Download the next chunk


(_downloadBuffer, 0, _downloadChunkSize, new AsyncCallback(DataReceived), this);

//Close the file _fileStreamObj.Close();

//Asks the user for confirmation if he or she wants to //install the downloaded updates if (MessageBox.Show("Updates downloaded. Would you like to install the updates now?", "Install?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Buttonl) == System.Windows.Forms.DialogResult.Yes)

//Launch the cab file Process.Start(_localCabPath, "");

//Update local version information UpdateLocalVersion();

//Updates the progress bar private void UpdateProgress(Object sender, EventArgs e) {

pbDownload.Value = _totalBytesDownloaded; Application.DoEvents();

//Retrieves the current application path private string GetCurrentApplicationPath() {

string _path =

System.Reflection.Assembly.GetExecutingAssemblyO .GetName().CodeBase; return System.IO.Path.GetDirectoryName(_path);

Your updater service is now complete! To test this application, ensure that an ActiveSync connection is properly set up first. When your application loads, you will notice that the current version is set to 1. Clicking the Check for Updates button retrieves the latest version information from the web service and displays it in the gray panel (shown as follows):

This tool allows you to check and download the latest updates far the SalesForce application

Current version: 1

Check for Updates

Latest version: 2 Version date: 1/12/10 Download size: 2,500,000 bytes

Download & install updates

When you click the Download & install updates button, this will initiate the download process. Once the download is complete, you will be prompted to install the updates (shown in the following screenshot).

After installing the CAB updates, the current version number in your XML file is automatically updated. If you launch the application again from your mobile device, you will notice that the current version now displays the value 2.

Don't launch the application from Visual Studio this time, as doing so will deploy the original XML file over to your mobile device and overwrite the copy on the device.

If you click Check for Updates now, it will prompt you with a message notifying that the application is already up to date.

Was this article helpful?

0 0
iPhone and iPad App Cash

iPhone and iPad App Cash

Discover how a single application could generate $1000's of dollars, instantly. The simple, low cost system for outsourcing app development to freelancers. How to quickly evaluate applications so you can create a high profit one of your very own. The fastest way to leverage the popularity of iPhone and iPad apps to skyrocket your income. Top methods for promoting your application for maximum exposure.

Get My Free Ebook

Post a comment