Author

I am Joannes Vermorel, founder at Lokad. I am also an engineer from the Corps des Mines who initially graduated from the ENS.

I have been passionate about computer science, software matters and data mining for almost two decades. (RSS - ATOM)

Meta
« Embedding maths in a Google Gadget | Main | Migrating from OnTime to Trac, a short review »
Tuesday
Aug192008

Creating an auto-update framework with WiX

The WiX does it job at letting you create Microsoft Installer packages (known as.msi files), but it involves it own set of weird peculiarities.

For my uISV, I have designed a minimal auto-update framework for WinForm applications. The spec was the following: the user can click on Check for update, and will optionally be notified if a new version is available. In such event, the user is proposed to upgrade toward the new version. Three clicks total, not bad (counting one click for the UAC notification under Vista).

First, let me introduce a word about minor revisions and major revisions as defined by the Microsoft Installer.

  • A minor revision is a revision that simply upgrade in place the very piece of software.

  • A major revision installs another software version, side-by-side with the old version.

For a simple upgrade framework, we will obviously stick with minor revisions

So far, all this well and this framework should be completely straightforward to do, yet some MSI absurd behavior is making the design much more difficult than it seems.

First, the MSI installer is taking into account the account the MSI file name. Any upgrade attempt with different MSI file name will be considered as a major upgrade. Apparently, this behavior based on some lame and deprecated considerations related to CD-ROM installations.

Thus, when your auto-update framework download the latest MSI package, it must be first be renamed to match the name of the MSI package at install-time. Yet, web browser just happens to frequently renamed downloaded files. For example, when people just download twice the very same file, your MSI package Setup.msi is renamed Setup[1].msi. Not even considering the situation where the users willingly rename the MSI file (why shouldn't they be permitted to do that?).

So you need to get the MSI name out of the Windows registry to figure out what was the file name at installation time. Well, it happens that this information can be found at
HKEY_CURRENT_USER\Software\Microsoft\Installer\Products\PRODUCT-CODE\SourceList\PackageName where PRODUCT-CODE is a token associated to your product.

One could have thought that it would have been natural to use the ProductId as defined in the MSI package (and your WiX project file) as PRODUCT-CODE, but some developers rightly send from hell, decided that it wasn't fun enough.

So, they settled for an arithmetic permutation of the ProductId. That's right, you can actually infer the PRODUCT-CODE by applying a not-too-simple permutation scheme on your original ProductId. For those would do not wish to loose as much time as I did on this matter, here is a PowerShell function to produce the conversion (this code is based on this thread):

# Get-MsiGuid
# By Joannes Vermorel, 2008
# Convert PackageId GUID (as provided in WiX) into ProductCode GUID (as used by MSI).
# Usage: Get-MsiGuid 'FOO-GUID-1234'

function Get-MsiGuid
{

param(
[string] $guidToken = $(throw "Missing: provide the GUID token to be converted.")
)

begin
{
}

process
{
$origGuid = new-object System.Guid $guidToken
$raw = $origGuid.ToString('N')
$aRaw = $raw.ToCharArray()

# compressed format reverses 11 byte sequences of the original guid
$revs = 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2

$pos = 0
for( $i = 0; $i -lt $revs.Length; $i++)
{
[System.Array]::Reverse($aRaw, $pos, $revs[$i])
$pos += $revs[$i]
}

# Passing the char array as a single argument
$n = new-object System.String (,$aRaw)
$newGuid = new-object System.Guid $n

# GUID in registry are all caps, ouput formats are N, D, B, P
write-output( $newGuid.ToString('N').ToUpper())
}

end
{
}

}

As a final note, the small auto-update framework is available as open source as part of Lokad Safety Stock Calculator on Sourceforge. The update information is directly grabbed from a PAD file (Portable Application Description).

Reader Comments (2)

1. Wow, WiX certainly looks like an acronym for "Wicked Xcopy".

2. "HKEY_CURRENT_USER\So..." breaks the line and goes beyond the column.

August 19, 2008 | Unregistered CommenterRinat Abdullin

Hi Pal,

Good site. Some useful and informative comments man :) I know, I am creeping,lol. Hopefully I can produce something like this myself. Who did you get your templates from?

Hopefully some of you guys could help me out a little here. I am hoping to find someone who I was reliably informed told used to be a member here. They used to use the name 'Alienlens'.

Because I am hoping to start my own website on health type goods for stuff such as: http://www.buyteethwhiteningstrips.com" rel="nofollow"> whitening teeth (hence the where did you get your templates from,lol) but am having realllll difficulty getting hold of dropshippers for these goods. I had been in touch with this guy but my PC got stolen and unfortunately had all my contact details on it (I know, I know, should have backed it up :( )

So if you guys have heard or seen anything of him could you send me a message please? Failing that maybe one of you folks knows someone?

And, which hosting do you use as I keep informed not so good tales about the host I am thinking of placing my site with. Also any other helpful tips you could give re starting up my site would be most useful and gratefully appreciated.

I hope that one of you has helpful knowledge about this

Thanks Mate,

October 18, 2009 | Unregistered Commenterdscogginsd
Comments for this entry have been disabled. Additional comments may not be added to this entry at this time.