Google Chrome setup

Google today released (after a bit of a comic-book pre-release, presumably due to the Labor Day holiday in the US) Google Chrome, its long-rumored open-source browser. Plenty of people will talk (endlessly) about the implications of another browser and how well Google Chrome and Chromium (the open source project) do the job. Blah, blah. Whatever. What’s really interesting is a couple of choices Google made about deployment:

  1. The Google Chrome download is a svelte 474K bootstrapper that downloads the setup bits. No offline installer is available (unless it’s well-hidden).
  2. Google Chrome is a "composite" setup: The guts of the application are installed by a non-MSI self-extractor. However, Google Chrome includes Google Gears, the browser add-in/library that adds a bunch of functionality for making apps-in-the-browser more powerful. The Gears in Google Chrome is installed by an MSI package. And yes, it’s built with WiX.
  3. The Google Updater is no longer a LocalSystem service; instead, it starts at logon from the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run registry key.
  4. Last and absolutely not least: Google Chrome is a per-user application. It even installs in the per-user LocalAppDataFolder. (The included Google Gears is marked as "UAC compliant.")

That Google Chrome is a per-user app is amazing. Even with UAC on Windows Vista and Windows Server 2008, it’s so easy to say that "everyone’s used to needing admin privileges to install." That Google took the extra effort to limit themselves to the capabilities of a per-user app says a lot about their desire to have:

  • a low-impact setup
  • and absolutely no barriers to entry.

I wonder if it’s the start of a trend…

Testing your deferred and rollback custom actions

When you include deferred custom actions — that somehow modify the machine — in your setup, you have two big responsibilities:

  1. Provide rollback custom actions that "undo" what the deferred CAs do so that the installation transaction is actually transactional.
  2. Test.
  3. Test.
  4. Test.

OK, so numbers 2 through 4 are kinda the same but not really: Even a simple installation (say, without patching or upgrades) has three different scenarios you need to test when you have deferred/rollback custom actions:

  1. Installation rollback.
  2. Repair rollback.
  3. Uninstallation rollback.
  4. All of the above.

The right behavior for each kind of rollback is usually the opposite action. Rolling back installation is uninstallation. Rolling back uninstallation is installation. Rolling back repair is usually installation. Mixing installation, repair, and uninstallation is possible if your package has user-selectable features and users go into maintenance mode to turn on and off features. And, of course, it’s always an option from the msiexec.exe command line using the ADDLOCAL/ADDSOURCE/ADDDEFAULT, REMOVE, and REINSTALL properties.

Testing rollback means testing failure

Windows Installer initiates rollback when an action fails, so to test rollback you need to cause a failure. WiX includes an easy way to trigger failure: The WixFailWhenDeferred custom action, part of WixUtilExtension, triggers a failure when it’s executed. Include it in your package by referencing WixUtilExtension (in your Votive .wixproj or via the -ext switch to the light.exe command line) and adding a CustomActionRef to your package authoring:

<CustomActionRef Id="WixFailWhenDeferred" />

WixFailWhenDeferred automatically schedules itself in InstallExecuteSequence before InstallFinalize, with a condition of:

WIXFAILWHENDEFERRED=1

The condition means that you can have one package to test all the different possible combinations of "normal" installation and rollback. Just pass the WIXFAILWHENDEFERRED=1 property value on the msiexec.exe command line to trigger rollback. For example:

msiexec /qb- /i intermediate.msi /L*vx installfail.log WIXFAILWHENDEFERRED=1
msiexec /qb- /i intermediate.msi /L*vx install.log
msiexec /qb- /fvamus intermediate.msi /L*vx repairfail.log WIXFAILWHENDEFERRED=1
msiexec /qb- /fvamus intermediate.msi /L*vx repair.log
msiexec /qb- /x intermediate.msi /L*vx uninstallfail.log WIXFAILWHENDEFERRED=1
msiexec /qb- /x intermediate.msi /L*vx uninstall.log

WixFailWhenDeferred has been in WiX v3 weekly releases since April.

VirtualBox 1.6.2 drops VBScript

As I mentioned previously, one of my favorite examples of a tight, clean Windows Installer package for a real product–VirtualBox–succumbed to a dreaded VBScript custom action when they released v1.6.0. Predictably, it caused errors (during uninstallation, because this custom action ran during uninstall only).

VirtualBox 1.6.2 dropped that custom action. The VirtualBox installers still have a few ICE errors and warnings so here’s hoping the VirtualBox team continues cleaning those up.

The case of the missing Mergemod.dll in WiX v3.0.4123

There’ve been a couple of reports that WiX v3.0.4123 doesn’t include mergemod.dll. That’s unfortunate because it’s a really annoying bug and worse, I was the last one to touch mergemod.dll (to fix 1965131) so it was probably my fault.

I couldn’t reproduce the problem, however; mergemod.dll was present in Wix3.msi, Wix3_x64.msi, and wix3-binaries.zip. I was about to ask for install logs to investigate when a likely cause occurred to me. The bug fix was to revert from a version of mergemod.dll with a bug to a prior one that doesn’t have the bug. Unfortunately, downgrading files is problematic with major upgrades: Windows Installer wants very much to keep higher-versioned files around. After all, the latest version probably has all the latest bug fixes, right?

If you install WiX v3.0.4123 over v3.0.4116, the log will contain a line like this:

MSI (c) (34:D4) [10:47:26:734]: Disallowing installation of component: {AAF02F71-9684-4F4F-8EEA-FC99A61EAA9A} since the same component with higher versioned keyfile exists

Simple workaround: Uninstall the earlier version of WiX, then install v3.0.4123.

Make sure features are always enabled so they can be removed

The WiX installer had a bug that I noticed during our transition from Visual Studio 2005 to Visual Studio 2008. If you had the Votive feature installed for VS2005 and VS2008, then uninstalled VS2005, the Votive feature was "orphaned" and couldn’t be uninstalled. The cause is that the Votive features are enabled only when the corresponding version of Visual Studio is installed. (The Feature/@Level attribute is 0 with a Condition child element to enable it.) MSI sees the feature as disabled in maintenance mode and won’t remove it.

Oops.

The solution is easy, though: Add OR REMOVE to the condition that enables the feature. That ensures the feature is enabled during whole-product uninstall or an attempt to remove that particular feature.