2009/07/02

How to Use the AutoUpdater in InstallBuilder

In version 6.0 of InstallBuilder, we started shipping a new tool called AutoUpdater . This tool allows you to enable users to check for, download and apply updates for your software on their machines, getting the necessary files through HTTP or FTP. Although the Autoupdater is not yet available through the InstallBuilder GUI, it is very simple to configure.

How Does it Work?

There is a binary file which will poll the server to get information about the software versions available. The behavior of this binary is:
  • Read the INI file that contains information about where to contact the server and which version is currently installed (which should be delivered together with the binary)

  • Get the XML file from the server, which contains available versions for each platform.

  • If there's a newer version available (checking that the version ID received is higher than the current one stored in INI file), download and install it or notify the user (return code = 0) if it is run in unattended mode.
This binary may be customized to fit your needs using the command line tool 'customize' which is available in the AutoUpdater directory after performing InstallBuilder installation. The binary may be generated for several platforms: windows, linux or linux-x64; and an XML file will be used to indicate the tool how should the updater be customized.



The syntax to use the tool is:

{IB_installdir}/autoupdater/bin/customize build /path/to/project.xml [windows,linux,linux-x64]

The project XML file must have the main tag '<autoUpdateProject>' containing a list of customizations. The ones currently available are:
  • General settings: allowLanguageSelection, allowedLanguages, customLanguageFileList, rebootRequired (after performing update), requireInstallationByRootUser (only the Administrator can run Autoupdater), saveRelativePaths, singleInstanceCheck (check that theres only one instance running)

  • Application: fullName, shortName, vendor, version

  • Modify view: height, width, leftImage (163x314 GIF or PNG), logoImage (48x48 GIF or PNG), splashImage(GIF or PNG image), splashScreenDelay, disableSplashScreen, overrideGtkButtonText, wmImage (48x48 GIF or PNG shown in the window manager task bar on Unix systems)

  • Windows binary options: windowsExecutableIcon, windowsResourceComments, windowsResourceCompanyName, windowsResourceFileDescription, windowsResourceFileVersion, windowsResourceInternalName, windowsResourceLegalCopyright, windowsResourceLegalTrademarks, windowsResourceOriginalFilename, windowsResourceProductName, windowsResourceProductVersion

After applying the customizations, the new file may be found inside {IB_installdir}/autoupdater/output.

The INI file should be delivered together with the update binary containing next fields inside [Update] section:
  • URL: The URL of the server from which the updates XML file should be obtained

  • version_id: The identifier of current installed version

  • update_download_location: The temporary path where downloaded installers should be stored

  • check_for_updates: It is possible to enable and disable the AutoUpdater on demand by setting this boolean value

The server XML file with latest version details should be present on the server located at the URL provided in the INI file with the following information inside the '<installerInformation>' tag:
  • version: name of the version to be shown to the user

  • versionId: version identifier

  • platformFileList: list of installer names by platform

  • downloadLocationList: list of download locations (downloadLocation), each containing a URL which points to a mirror where the software can be downloaded

Note: versionId must be an integer which takes higher values for the newest versions.

Simple example

Imagine we have an application called 'My Application' and we want to include AutoUpdater functionality in version 1.0.0. We may also want, for example, for the update process to be run by an Administrator and while only one process is being run. We can generate a custom binary having the appropriate application name, version and required flags:

<autoUpdateProject>
<fullName>My Application</fullName>
<shortName>myapp</shortName>
<vendor>Acme Inc.</vendor>
<version>1.0.0</version>
<singleInstanceCheck>1</singleInstanceCheck>
<requireInstallationByRootUser>1</requireInstallationByRootUser>
</autoUpdateProject>

You may want to change the images and icons to have application specific ones. To do so, you can add the options: leftImage, logoImage, splashImage, wmImage. Once all desired options are included in project.xml file, we run the customize command:

{IB_installdir}/autoupdater/bin/customize.bin build project.xml linux
{IB_installdir}/autoupdater/bin/customize.bin build project.xml windows

After that, binary files for Linux and Windows should be found in AutoUpdater output directory.

Apart from the AutoUpdater binary, you will need to setup a server with the new installers and update.xml file. In our case, we will use a server running locally in port 8080. (You can easily setup a web server using LAMPStack or WAMPStack from BitNami.org). We just need to copy there the latest installers and an update.xml file describing that version, the filenames and mirrors:

<installerInformation>
<versionId>200</versionId>
<version>2.0.0</version>
<platformFileList>
<platformFile>
<filename>myapplication-installer-2.0.0.exe</filename>
<platform>windows</platform>
</platformFile>
<platformFile>
<filename>myapplication-installer-2.0.0.bin</filename>
<platform>linux</platform>
</platformFile>
</platformFileList>
<downloadLocationList>
<downloadLocation>
<url>http://127.0.0.1:8080/downloads/</url>
</downloadLocation>
</downloadLocationList>
</installerInformation>

where versionId has been set to a higher integer value than previous ones and we have configured a single mirror. We can include any number of mirrors by adding multiple download location elements though. That way, the installers will be downloaded from:

http://127.0.0.1:8080/downloads/myapplication-installer-2.0.0.bin
http://127.0.0.1:8080/downloads/myapplication-installer-2.0.0.exe

AutoUpdater should be able to locate that update.xml file as well as know which software version is currently installed. That is done using an “update.ini” file with the following content:

[Update]
url = http://127.0.0.1:8080/update.xml
version_id = 100
check_for_updates = 1
update_download_location = /tmp

In this case, update.xml will be obtained from localhost, saving temporary installers inside the /tmp path. The application upgrade process will be done if received version ID is greater than 100.

Once we have the files available and update.ini is in the same path as the AutoUpdater binary, we can check its behavior:

When it is started , the rules included in customization will be checked: if the user is not an Administrator, he or she will be notified and the AutoUpdate process ends. If there is another instance already running, a notification will let the user know and he or she will be able to chose if the process should continue or not. If both requirements are met, a welcome screen will appear.

Here is what the process will look like from the user's perspective:



After clicking 'Next' button we'll get a screen to configure a proxy if it is necessary.



It will contact the server and check if there are new versions available. If there is an update, the following screen will be shown:



If you click 'Next', a new window with the list of mirrors is shown.





Once the new version is downloaded, the installer is started

Adding AutoUpdate to an Existing InstallBuilder Project

The only steps required to include the new feature as part of the application installation is to copy the appropriate AutoUpdate binary file for each operating system and place update.ini file in the same folder. For instance, we can define a component in the following way:

<component>
<name>autoupdater</name>
<description>includes tool to perform updates</description>
<canBeEdited>0</canBeEdited>
<selected>1</selected>
<show>0</show>

<folderList>
<folder>
<name>autoupdaterwin</name>
<destination>${installdir}</destination>
<platforms>windows</platforms>
<distributionFileList>
<distributionFile origin="autoupdater-windows.exe"/>
</distributionFileList>
</folder>
<folder>
<name>autoupdaterlinux</name>
<destination>${installdir}</destination>
<platforms>linux</platforms>
<distributionFileList>
<distributionFile origin="autoupdater-linux.bin"/>
</distributionFileList>
</folder>
</folderList>

<postInstallationActionList>
<writeFile>
<path>${installdir}/update.ini</path>
<text>[update]
url = ${update_xml_url}
version_id = ${application_version_id}
update_download_location = ${system_temp_directory}
check_for_updates = 1
</text>
</writeFile>
</postInstallationActionList>
</component>

Where the 'update_xml_url' installer variable must be setup to point to where update.xml can be fetched and 'application_version_id' must be modified to a higher value on each installer update. Of course, it will be also needed to copy the 'autoupdate-*' binary files to project directory.

Using AutoUpdate as a notifier

Another approach can be to include the AutoUpdate but use it as a notifier which just checks if there are new updates available or not. This can be achieved calling the tool in unattended mode:
$ autoupdater.bin --mode unattended

The exit code will be 0 if an update is available and 1 if not. You can use this approach to show a 'There's a new update available' message to users. To do so, you just call the process in background and generate the message if the returned code is 0:

if (system(“path/to/autoupdater –mode unattended”) == 0){
printf(“Update available. Run autoupdate to apply it.”);
}

Something similar may be added when the application starts, or as a cron task if it is a web application, so that the user detects that there's a new update without having to run AutoUpdater manually to check it.

For more information on AutoUpdater, please see the AutoUpdate documentation included with each download of InstallBuilder.

You can also watch the following video, that displays the needed steps:



No comments: