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.

Microsoft Source Analysis for C# released

Microsoft Source Analysis for C# — known inside Microsoft as StyleCop — is now available. We use StyleCop on new WiX code, in addition to FxCop to analyze code for style consistency and correctness. Now that StyleC…er, Microsoft Source Analysis for C# is available outside the campus grounds, we can include the settings files we use in the WiX codebase.

StyleCop is a Visual Studio package that integrates analysis commands in the Solution Explorer and a tool window to show analysis results. StyleCop also includes MSBuild tasks so you can make analysis runs part of your daily builds.

Naturally, the Style…dammit…Microsoft Source Analysis for C# installer is authored in WiX. The package is extremely clean. There are no ICE errors and only ICE33 warnings about non-advertised COM registration. The only custom actions come from WixUIExtension and WixVSExtension. The UI is built with WixUI, though the StyleCop team chose to use some logo-themed white bitmaps rather than the classic-yet-modern red.

The first few times you run StyleCop on existing code, you’re bound to be surprised and probably frustrated. The rules are, after all, about enforcing a consistent coding style. Unless you happen to already be using the StyleCop style, you’ll get a lot of “violations” that seem quite arbitrary. Yep, and that’s the point: Coding style discussions are pretty much religious wars over arbitrary decisions. (Yes, there are exceptions, but mostly it’s personal esthetic choice. Except for tabs versus spaces; don’t mess with tabs versus spaces!)

Just stick with StyleCop style and you’ll be consistent, even if elements of the style aren’t your personal favorite.

Google Earth setup experience

Google announced the release of Google Earth 4.3 today. Given the recent release of their WiX-based setup for the Google App Engine SDK, I had to give it a shot. (It helps that my day job also deals with 3-D terrain imagery.)

When you click the link to “Download Google Earth 4.3” (and accept the EULA), you download not Google Earth but “Google Updater.exe.” Run it and it starts downloading the Google Earth installer.

Personally, I much prefer to download the actual installers for the software I use. Some of it’s purely practical: I can stick it on a network and put it on multiple computers (EULA permitting, of course) without waiting for multiple downloads. Perhaps more importantly, for the paranoid among us, is the ability to virus-scan the installers. (Google Updater requests elevation, so it has admin rights to install multiple packages.)

Google Updater also runs as a startup app, optionally showing an icon in the increasingly-unusable system tray. (Yes, I know it’s technically the “notification area,” but come on, who calls it that?) I don’t think I need 24/7 instant access to software that doesn’t get updated that often. In fact, I’m sure I don’t.

Naturally, installing a packaging system with update capabilities is a boon to many users (and Google itself, of course, which has a nicely visible entry point to suggest additional apps for download). Apple does it with iTunes and Microsoft does it with Windows Live. Luckily, Google Updater has its own entry in Add/Remove Programs so you can remove it without impact to Google Earth.

Google Earth installer

The Google Earth installer is built with InstallShield, using its support for “dynamic file linking.” (If you haven’t used it, think of running Heat or Tallow with every build.) Interestingly, it uses the CAQuietExec custom action from WiX and has wixca.dll in the Binary table.

The .msi package fails ICE validation, with errors in ICE03, ICE15, ICE34, ICE38, ICE43, ICE44, ICE57, ICE64, and ICE99, and warnings in ICE45, ICE60, ICE82, ICE86, and ICE91.

There are 36 custom actions, some of which are mildly disturbing:

  • registerFlashSOL is a deferred, no-impersonate custom action that runs an included .exe with a “-install” command-line switch. Oh joy: self-reg.
  • InstallToolBarCA is an immediate custom action that runs an installed .exe. It’s not scheduled and is only available from the UI sequence – the one that’s suppressed because Google Updater runs the installation silently.
  • SetGEUserStats is another custom action run only from the suppressed – but still included – UI sequence.
  • SET_RES_READ_ONLY sets QtExecCmdLine to run the WiX CAQuietExec custom action. What is it hiding? It’s running attrib.exe to turn off the read-only attribute on a recursive set of files/directories. Doesn’t the File table let you control the read-only attribute? Yes, it does, but apparently not when you use InstallShield’s dynamic file linking to harvest a directory tree at build time. In a previous life, I used that functionality and turned off the read-only attributes in the build script before harvesting. Doing it as part of installation is bad karma on Google’s part.

Overall, it’s not a bad installer, but I hope Google cleans it up a bit before it loses the “beta” label.

Two great tastes: Agile development and distributed, declarative setup

I’ve had the good fortune to work on several agile software-development teams over the years. If you’ve ever hated having software you’ve developed sit on the shelf for months or years until the next release, shipping several times a year feels good. Shipping almost every month is even better. Shipping almost every week is phenomenal.

Most of the principles of the agile manifesto reinforce the idea that shipping software often is how to best deliver customer value. To ship often, you need predictability:

  • Finish all the work associated with a feature.
  • Make sure it’s of ship quality.

Done versus done-done

The waterfall model of designing, then coding, then throwing over the wall to test, then fixing bugs, then throwing over the other wall to setup–yes, of course I’m going to talk about setup–is just procrastinating. Sure, it’s more fun to start working on the next new thing, but it’s just postponing the work required to get a feature really done and ready to ship.

Setup development, like testing, is often considered one of the “taxes” of software development that is best put off as long as possible. But if you want to deliver shippable software on a rapid schedule, paying taxes late doesn’t work; you might get to April 15th and discover that you have more bugs than you can fix by midnight. Instead, you pay your taxes as you go along so there are no surprises when you get to the last day and you want to ship.

Rather than developers considering themselves “done” when they’ve written some code and debugged it, developers need to get “done done” by providing code, unit tests, acceptance tests, and setup.

WiX supports “done done” by easily integrating into the development build cycle. Every member of an agile team can author setup. That prevents the lone setup developer, who probably supports multiple product teams, from being a bottleneck.

Plus, if developers are responsible for their own setup authoring, they’re less likely to push bad design decisions onto the setup developer’s shoulders.

Keep quality high and take the weekends off

Agile methodologies bring a whole set of tools and processes to help keep quality high and ready to “ship on a dime,” like:

  • Test-driven development to produce high-quality designs and code
  • Automated acceptance testing to reduce the need for armies of testers to validate the whole system at the end

Add some setup flavor:

  • Make sure that “done” for every feature includes its setup authoring.
  • Run your automated acceptance tests from official setup packages, not from local builds.
  • Build upgrades and patches and create automated tests to ensure you can service the product.
  • Use only fully declarative custom actions–they make it easier to handle patching, upgrades, and repair.

Frequent, automated testing tells you if your code (and setup) do what they’re supposed to (or not–at least as far as the tests are concerned). Adding setup into the testing mix helps ensure that your setup is ready too.