It’s time to experiment

Last month, I posted a plea for help to try to figure out why sometimes (or rarely) (or frequently), Windows Installer fails to set an internal property that causes a never-ending “please wait” dialog. I got lots of feedback—thanks!—but unfortunately, nothing that helped me pinpoint a cause or a solution.

So it’s time to make an guess. Let’s call it an educated guess but as I can’t reproduce the problem, I’m not sure it’s entirely educated.

Coming in the next weekly release of WiX is a mechanism to opt out of the costing popup dialog. And although it’s an opt-out mechanism, for now it’s opted-in by default. The idea is to see quickly if the change fixes the problem. If it does, we’ll keep the opt-in default for WiX v3.5. If not, we can either back out the change or just change the default to opt-out.

So what’s the change? Before, all the dialogs that initiated an install transaction used a SpawnWaitDialog control event with a condition of CostingComplete=1. The dialog would pop up until the condition was met. Now, the condition includes the bind-time WiX variable WixUICostingPopupOptOut. WixUICostingPopupOptOut defaults to 1, so the condition is always true and the popup never appears.

You can override WixUICostingPopupOptOut in your project with a value of 0 to return to the previous behavior:

<WixVariable Id="WixUICostingPopupOptOut" Value="0" />

So, please grab the next release of WiX and try out your previously problematic installers. We want to fix this problem before we start locking down WiX v3.5 for RTM.

Update: You can get the weekly release here.

Working hard or hardly working?

Don’t complicate your setups by doing more than you have to. Here are a few things I’ve run into lately of people doing more than they have to and opening themselves up to potential bugs or increased risk of getting something wrong.

  • Some attributes are optional, really. Rob and I have blogged before about the language enhancements sneaking into WiX v3.5. Those enhancements focus on simplifying authoring, by collapsing elements (MajorUpgrade) or providing smart attributes (Component). I suspect many people rely on IntelliSense in Visual Studio when authoring their WiX source files. IntelliSense is pretty close to sliced bread on the greatness scale of inventions, but it has a significant downside in the current implementation in Votive: It lists all possible elements and attributes in the WiX schema, with no “intelligence” behind which are most important. So you get the positive IntelliSense feedback of providing values for every attribute. It’s addicting but you can fight it. (To be fair to IntelliSense, it’s just using the default XSD schema support in the XML language service; if someone were to add a WiX language service to Votive, IntelliSense could be much better.)
  • Manually marking package and component bitness. MSI doesn’t support platform-neutral packages or components: They’re either 32-bit (x86) or 64-bit (x64 or IA64). In your authoring, you can specify a package’s platform using the Package/@Platform attribute. Components are 32-bit by default; you can specify that they’re 64-bit by specifying “yes” as the Component/@Win64 attribute value. In a package full of 64-bit components, you have to specify @Win64=”yes” for every component. It’s typical to want to produce both 32-bit and 64-bit packages from the same WiX source, so a common approach is to make the @Win64 attribute value a preprocessor variable. Or, just let WiX handle it for you: Specify the –arch switch at the candle.exe command line or the <InstallerPlatform> property in a .wixproj MSBuild project. When you specify x64 or intel64, Candle automatically sets the package and components in the file being compiled as 64-bit. It’s still useful to be able to say “Win64=’no’” for those components that are 32-bit even in 64-bit packages. Of course, that’s also legal in 32-bit packages, so it’s safe to hard-code.
  • Unnecessarily nuking registry keys. The RegistryKey/@Action attribute lets you specify some of the “special” Registry table functionality that MSI supports. Specifying create lets you create an empty registry key; createAndRemoveOnUninstall tells MSI to delete the key and all values during uninstall. That’s useful functionality if your application creates additional values at runtime—but for per-machine registry keys (under HKEY_LOCAL_MACHINE) most apps don’t create additional values because it would require elevation. (The not-quite invisible hand of UAC gently guides developers toward good app behavior.) If you omit the @Action attribute or specify none, MSI will still delete the registry key if it deletes all the values in it (and so on, recursively down the registry key hierarchy). That’s the default; you don’t have to ask MSI to remove the registry entries it writes. So if you need to nuke your keys, go ahead, but otherwise, don’t bother.

By the way, all of these things work in WiX v3.0 rtm.

Bug hunting

There’s a bug that the WixUI “Please wait while the installer finishes determining your disk space requirements” dialog is intermittently shown forever, never finishing the costing process to continue installation. I’ve seen that bug before have never been able to reproduce it reliably. The disk costing process is something Windows Installer does in the background while the wizard UI is running; .msi packages have no real control over the process, other than which features are enabled at the start of the UI sequence.

Here’s the problem: I don’t think it’s a bug in WiX or WixUI. MSI owns the costing process and as costing works almost all the time, there isn’t a simple answer like “oh yeah, a rich-edit control on the first dialog breaks costing.” I suspect that there’s a bug in MSI but before I go to the MSI team, bug in hand, I need more data. Here’s where you come in: Help us gather more data to narrow down the bug.

  1. Logs. It’s a reflexive request that verbose MSI logs are a vital part of figuring out any setup bug. In this case, they might not be that helpful, as the logs I’ve seen, including those attached to the bug, just show a lot of time passing between log entries.
  2. OS version. Which version of the OS? Which edition? x86 or x64? Which service pack?
  3. Virtuality. Does the bug occur in virtual machines or on “real” machines? Which virtual machine technology (e.g., Virtual PC, Hyper-V, VMware, VirtualBox)?
  4. MSI version. If it is a bug in MSI, narrowing down which versions are afflicted the worst would be key. (For example, I’ve never seen the bug occur on MSI 5.0 in Windows 7.)
  5. Frequency. How often does the bug occur?
  6. .msi package data. How big? How many files? How many components?
  7. WiX and WixUI data. Which version of WiX are you using? Which WixUI dialog set? How have you customized it?
  8. Packages. If you can provide packages that demonstrate the problem, please do so. Obviously, you might not be able to share your actual package content but does the bug still reproduce if you replace your actual files with zero-byte replacements?

If you’ve seen this problem, please help: Add your comments to the bug on SourceForge and attach your logs and packages.

Help us WiX community, you’re our only hope.

Update, 5 April 2010: Added Virtuality – I got a report that the bug occurs most often on Virtual PC virtual machines and it seems to be a common issue on various blogs.

Lux unit testing, now with extra mutations

I’m currently spending a lot of time working with custom actions, removing them where I can and improving them where they’re still necessary. The biggest change I’m making is to make the custom actions data driven using the immediate/deferred/rollback custom action triad. One of the advantages in doing so is that I can use Lux to help test my work. One of the advantages of that is that real-world experience is the best way to improve tools.

One of the challenges of developing data-driven custom actions is testing all the combinations of state that affect the custom action data immediate custom actions pass to deferred and rollback custom actions. Because Lux test packages don’t modify the machine, testing the full set of possible states is difficult. Providing known state is a strength of traditional unit-testing techniques, however; if your custom action code is well factored, it should be a simple task to provide a test double that arranges hard-coded state information that you can then test against.

Naturally, I wanted to figure out how I could provide the best of both worlds in Lux. Here’s what I came up with: test mutations. From the doc:

Test mutations let you author unit tests with different expected results. The mutation id is passed as the value of the WIXLUX_RUNNING_MUTATION property. Your custom action, typically in an ‘#ifdef DEBUG’ block, retrieves the WIXLUX_RUNNING_MUTATION property and mock different behavior based on the mutation. To author test mutations, use the Mutation element with UnitTest elements as children. For example:

<lux:Mutation Id="SimulateDiskFull">
  <lux:UnitTest … />
</lux:Mutation>

Nit runs the test package once for each mutation, setting the WIXLUX_RUNNING_MUTATION property to one mutation id at a time. Tests that aren’t children of a mutation are run every time.

Test mutations are a fairly simple change but one I hope simplifies combining traditional unit-testing techniques with declarative assertions.

Lux’s test mutations will ship in the next weekly release of WiX.

WiX, MSBuild v2.0, and x64 systems

WiX v3.0 and v3.5 executables are available in .zip form and x86 and x64 .msi packages. The x64 .msi package was originally created because we need to install the WiX targets and tasks for 64-bit MSBuild into a 64-bit directory, something that’s not supported for x86 packages. Late in the WiX v3.0 development cycle, Jason made a change that lets 64-bit MSBuild use the targets and tasks in the 32-bit directory tree. Unfortunately, the special property used to allow that is present only in MSBuild v3.5, not MSBuild v2.0, so we still create the x64 .msi package.

Creating the x64 .msi package isn’t a huge burden on us but it’s led to some confusion, so we’d like to get rid of it. If you use 64-bit MSBuild 2.0 and the x64 WiX .msi package, please respond in the comments. If you use MSBuild 3.5 or the .zip WiX package or by checking WiX in to your source-control system, you’re not affected and can use the x86 WiX .msi package.

Posted in WiX