OurWord

A Tool for Bible Translators

Skip Navigation Links

Install & Check For Updates

This page describes my implementation of Check For Updates, which allows OurWord to update itself. This has proven necessary in order to keep all of the users of a data repository up-to-date with the code that understands the files within the repository. Without it, if I changed the format of a data file, older versions of OurWord would not handle that data file properly. Now, when a user requests a Send/Receive, OurWord first checks for updates and installs them if found; so that there are no longer any compatibility issues among the computers in a project.

Check for Updates is a three-step process:

1. OurWord invokes SetupManager.CheckForUpdates in-process. This method downloads the Manifest from the Internet and checks its version number to see if it is later than the installed version. If it is, then it downloads all of the files that have changed into a Download folder. It then invokes "..\Download\SetupOurWord.exe update", and shuts OurWord down.

2. SetupOurWord.exe launches, and invokes SetupManager.FinishUpdate. Now that OurWord has shut down, its first order of business is to remove any stale files that are no longer needed. It then installs files from the Download folder into the application folder, and into other destination folders; unzipping as appropriate. Note that SetupOurWord.exe is itself copied into the application folder, as it will be needed for the next CheckForUpdates command. When it is finished, is invokes OurWord and then shuts itself down.

3. OurWord launches and the user is back in control.

Initial installation is a similar process, and uses much of the same code:

1. The user navigates to the Download Page and downloads SetupOurWord.exe to his computer.

2. He double-clicks on SetupOurWord.exe, and answers the Windows User Access Control prompt. Since SetupOurWord is launched without the -update command argument, it clears out anything in the install folder. It then downloads all of the files from the Internet. Finally it invokes "..\Download\SetupOurWord.exe update", and shuts itself down.

3. The process continues in the same manner as the Check For Updates defined above, now at Step #2.

Implementation notes

A. Installation is done under the user's Application Data folder. In Windows 7 this is "C:\Users\JoeSmith\AppData\Local\OurWord." The download folder is a subfolder, "C:\Users\JoeSmith\AppData\Local\OurWord\Download." It is necessary to install here, rather than under Program Files, because people who log into Windows with a Limited User account only have access to this area. Thus any software that sports a CheckForUpdates feature will avoid the Program Files destination.

B. The Manifest is an xml file that contains a list of the files to download. OurWordManifest.xml is stored in the application's install folder. The CheckForUpdates process downloads the Internet version of OurWordManifest.xml to the Download folder, and then compares the contents of the two files to determine what to download and install. When the update is complete, the downloaded manifest is then moved into the application folder and becomes the current manifest.

The length attribute gives the file's length, which is used to see if the installed file is different from the one on the Internet; and in the progress indicator to indicate the progress of download operation.

The hash attribute is a hex form of the SHA-1 160-bit hash. It is claimed by Visual Studio's documentation that "small changes to the data result in large, unpredictable changes in the hash." We use the hash, together with the length attribute, to determine whether or not to download a file; and then as a checksum afterwards to determine if the download was successful.

The filename attribute is, of course, the name of the file to be downloaded.

C. OurWord's post-build process includes steps to build the manifest:

1. All built files are copied into a special Deploy folder, with commands along the lines of
copy "$(TargetDir)OurWord.exe" "$(SolutionDir)Deploy"

2. OurWordSetup.exe is called with a special flag that causes it to build a manifest of all of the files in the Deploy folder, and then place the manifest there. The command is
"$(TargetDir)OurWordSetup.exe" -g "$(SolutionDir)Deploy".

D. Deployment is then simply a matter of uploading everything in the Deploy folder to the appropriate place on the Internet; which is a folder under OurWordSoftware.org.

E. No provision for Patches-To-Stable versus Development releases has been made at this time. One possible approach would be to use a normal setup program for development releases, with CheckForUpdates disabled.

F. No provision has been made for modifying the Registry. Use of the Registry is somewhat contrary to the philosophy both of CheckForUpdates installation, and for cross-platform; and OurWord is moving away from its use.

G. Zip files are supported. The use of zip files serves both to reduce the number of bytes a user must download from the Internet, but also to organize install files as part of a project.The filename indicates the destination as follows:

The first 'word' of the filename must be one of the recognized possibilities:

- app - the root will be the application folder

- mydocs - the root will be the user's "My Documents" folder

- langdata - the root will be the Language Data folder (that is, C:\Users\JoeSmith\AppData\Local\Language Data)

Subsequent 'words' up until the final 'word' indicate optional subfolders under this root.

For example,

"app.loc.Localizations.zip" has all of its files unzipped in the "{app}\loc" folder.

"app.SupportingDlls.zip" has all of its files unzipped in the "{app}" folder. (This is where I put things like Chorus, Palaso, LinqBridge, etc. that do not change when I build my solution.)

"langdata.OurWordSample.Sample.zip" has its files unzipped in the "C:\Users\JoeSmith\AppData\Local\Language Data\OurWordSample" folder.

H. The ability to unzip files is handled by the ICSharpCode.SharpZipLib library. As a post-build step, I use Microsoft's ILMerge program to combine the SetupManager code with this library into a single executable, SetupOurWord.exe. This ensures that the installer has the ability to unzip files, independently of whatever is going on in the file download/copy process. The SharpZipLib weighs in at 188Kb, so the cost of this is that these bytes are downloaded during the update process if the SetupManager code has changed. (However I anticipate that SetupManager will rarely change.)

I. There is no good way to create a desktop shortcut. After some research via Google I finally went with including the IWshRuntimeLibrary and creating a shortcut at runtime if one doesn't already exist. The process is described here. No question this will not work on the Linux port. I call the method to create the shortcut as part of OurWord's Main method, which means that if one doesn't exist, it will be created. For MTTs this behavior should be fine; but power users who hate desktop icons will be unhappy that the OurWord shortcut keeps reappearing.

J. Mercurial is installed as just another zip. This is actually independent of this installer and I only make this note as an FYI. I include a file called app.mercurial.zip, which places the Mercurial tree as a folder underneath the OurWord install folder. At runtime I then set temporary environment variables to tell the system where to find mercurial's hg.exe file. Because Mercurial is now included in OurWord's installation, I can be assured that I know what version of Mercurial all users are using; which should help if an issue with Mercurial ever shows up.

K. It is possible to install without an Internet connection. One of the things that the SetupManager does in response to the -g flag, during OurWord's post-build process, is to create OurWordSetupFiles.zip. When SetupOurWord is run with no flags, if it finds OurWordSetupFiles.zip in the same folder, it installs the files within it rather than doing a download. So a person could put these two files on a memory stick and accomplish installations on a group of computers without going to the Internet. (Subsequent CheckForUpdates actions still require the Internet, however.)

My implementation has the following shortcomings which I hope to address soon:

1. No means of creating items in the Start Menu. For OurWord we've not really needed a Start Menu item, so I've not worried about it. The solution is probably similar (and equally distasteful) to the desktop shortcut described above.

2. Names and destinations are hard-coded as consts. Because SetupOurWord.exe must run as a standalone, I could not call it as a library and pass values in. So things like the Internet location are hard-coded. If you wish to use the code, and can think of a way to generalize this, let's talk!

3. Unit tests do not handle the some issues, in particular, those operations which involve downloading from the Internet.

Since OurWord is open-source you are certainly invited to use the code; but I'd sure appreciate it if you'd help me make it better.

Copyright © by John Wimbish 2004-2012. All rights reserved.