If you build setups of almost any size, you can get a “free” boost in build speed on any modern computer – i.e., one with multiple CPU cores. Just use multiple cabinets. Unfortunately, because the CAB API itself isn’t multithreaded, a single cabinet is built with one thread. Light’s multithreadedness kicks in when there are multiple cabinets, so each cabinet is built on one thread.

By default, Light uses the number of processors/cores in the system as the number of threads to use when creating cabinets. You can override the default using Light’s –ct switch or the CabinetCreationThreadCount property in a .wixproj project.

Multiple threads will make good use of your available CPU power but with more threads loading files and writing cabinets, sooner or later, you’ll reach a point where your disks will be thrashing or just be unable to keep up with a nice dual quad-core build server. You can experiment with CabinetCreationThreadCount, RAID 0, the WIX_TEMP environment variable, or simply writing the output package (and therefore its cabinets) to a separate drive.

You can use multiple cabinets both externally and embedded in the .msi package (using the Media/@EmbedCab attribute).

Posted in WiX at March 29th, 2008. No Comments.

WixCop is a WiX v3 command-line tool that serves two main purposes:

  • To upgrade WiX authoring to the current schema
  • To format WiX authoring according to a set of common formatting

Upgrade your authoring

The biggest reason that WiX v3 is currently marked as “beta” is that the WiX source schema – the set of XML elements and attributes – changed quite a bit from v2 to v3 and we’re not 100 percent sure that we’re done making breaking changes. (In fact, I’d bet good money that we’re done making breaking changes but we might make some more backward-compatible tweaks to simplify common tasks, like we’ve done a few times before.)

Moving from WiX v2 to v3 is a mildly annoying prospect if you’ve done it manually. To avoid that hassle, WixCop was born.

Likewise, moving from early to recent v3 builds would expose the changing schema – especially early on in v3 development, when Derek was busily taking WiX apart and rebuilding it. So WixCop also knows how to translate various versions of the WiX v3 schema to the latest.

Format your authoring

As WiX authoring is plain ol’ XML, formatting it could be accomplished with any XML-savvy text editor. But integrating it into a tool like WixCop means you can automate the formatting, maybe even run it as part of a build. Having consistent formatting makes it easier to see substantive differences in your version control’s differ and, more importantly, minimize “bad merges” when you move setup authoring among the multiple branches in your version control system.

WixCop’s formatting capabilities include my favorite-ever error message:

Microsoft (R) Windows Installer Xml Cop version 3.0.3907.0
Copyright (C) Microsoft Corporation 2004. All rights reserved.

x:\filename.wxs(17) : error WXCP0007 : The whitespace preceding this node is incorrect. (WhitespacePrecedingNodeWrong)

That’s right – whitespace can be incorrect.<g> Luckily, the definition of incorrect is configurable.

WixCop reference

WixCop’s command-line syntax is:

WixCop.exe [options] sourceFile [sourceFile …]

WixCop takes any number of WiX source files as command-line arguments. Wildcards are permitted. WixCop supports response files containing options and source files, using @responseFile syntax.

WixCop returns the following exit codes:

  • 0, when no errors are reported.
  • 1, when a fatal error occurs.
  • 2, when WixCop violations occur.

The following table describes the switches that WixCop supports.

WixCop switch Description
-? Show help.
-nologo Don’t show the WixCop banner.
-f Fix errors encountered in source files. This switch takes effect only for source files that are writable.
-s Look for source files in subdirectories.
-indent:n Overrides the default number of spaces per indentation level (4) to the number n you specify.
-set1filename Loads a primary settings file (see below). Note that there are no characters separating –set1 and the settings file name.
-set2filename Loads an alternate settings file that overrides some or all of the settings in the primary settings file. Note that there are no characters separating –set2 and the settings file name.

WixCop settings files

WixCop supports two settings files. Generally, the primary settings file is your “global” settings and the alternate settings file lets you override the global settings for a particular project.

Settings files are XML with the following structure:

<Settings>
<IgnoreErrors>
<Test Id=”testId” />
</IgnoreErrors>

<ErrorsAsWarnings>
<Test Id=”testId” />
</ErrorsAsWarnings>

<ExemptFiles>
<File Name=”foo.wxs” />
</ExemptFiles>
</Settings>

The IgnoreErrors element lists test IDs that should be ignored. The ErrorsAsWarnings element lists test IDs that should be demoted from errors to warnings. The ExemptFiles element lists files that should be skipped.

The following table describes the tests that WixCop supports.

WixCop test ID Description
Unknown Internal only: returned when a string cannot be converted to an InspectorTestType.
InspectorTestTypeUnknown Internal only: displayed when a string cannot be converted to an InspectorTestType.
XmlException Displayed when an XML loading exception has occurred.
UnauthorizedAccessException Displayed when a file cannot be accessed; typically when trying to save back a fixed file.
DeclarationEncodingWrong Displayed when the encoding attribute in the XML declaration is not ‘UTF-8′.
DeclarationMissing Displayed when the XML declaration is missing from the source file.
WhitespacePrecedingCDATAWrong Displayed when the whitespace preceding a CDATA node is wrong.
WhitespacePrecedingNodeWrong Displayed when the whitespace preceding a node is wrong.
NotEmptyElement Displayed when an element is not empty as it should be.
WhitespaceFollowingCDATAWrong Displayed when the whitespace following a CDATA node is wrong.
WhitespacePrecedingEndElementWrong Displayed when the whitespace preceding an end element is wrong.
XmlnsMissing Displayed when the xmlns attribute is missing from the document element.
XmlnsValueWrong Displayed when the xmlns attribute on the document element is wrong.
CategoryAppDataEmpty Displayed when a Category element has an empty AppData attribute.
COMRegistrationTyper Displayed when a Registry element encounters an error while being converted to a strongly-typed WiX COM element.
UpgradeVersionRemoveFeaturesEmpty Displayed when an UpgradeVersion element has an empty RemoveFeatures attribute.
FeatureFollowParentDeprecated Displayed when a Feature element contains the deprecated FollowParent attribute.
RadioButtonMissingValue Displayed when a RadioButton element is missing the Value attribute.
TypeLibDescriptionEmpty Displayed when a TypeLib element contains a Description element with an empty string value.
ClassRelativePathMustBeAdvertised Displayed when a RelativePath attribute occurs on an unadvertised Class element.
ClassDescriptionEmpty Displayed when a Class element has an empty Description attribute.
ServiceInstallLocalGroupEmpty Displayed when a ServiceInstall element has an empty LocalGroup attribute.
ServiceInstallPasswordEmpty Displayed when a ServiceInstall element has an empty Password attribute.
ShortcutWorkingDirectoryEmpty Displayed when a Shortcut element has an empty WorkingDirectory attribute.
IniFileValueEmpty Displayed when a IniFile element has an empty Value attribute.
FileSearchNamesCombined Displayed when a FileSearch element has a Name attribute that contains both the short and long versions of the file name.
WebApplicationExtensionIdDeprecated Displayed when a WebApplicationExtension element has a deprecated Id attribute.
WebApplicationExtensionIdEmpty Displayed when a WebApplicationExtension element has an empty Id attribute.
PropertyValueEmpty Displayed when a Property element has an empty Value attribute.
ControlCheckBoxValueEmpty Displayed when a Control element has an empty CheckBoxValue attribute.
RadioGroupDeprecated Displayed when a deprecated RadioGroup element is found.
ProgressTextTemplateEmpty Displayed when a Progress element has an empty TextTemplate attribute.
RegistrySearchTypeRegistryDeprecated Displayed when a RegistrySearch element has a Type attribute set to ‘registry’.
WebFilterLoadOrderIncorrect Displayed when a WebFilter/@LoadOrder attribute has a value that is not more stongly typed.
SrcIsDeprecated Displayed when an element contains a deprecated src attribute.
RequireComponentGuid Displayed when a Component element is missing the required Guid attribute.
LongNameDeprecated Displayed when a an element has a LongName attribute.
RemoveFileNameRequired Displayed when a RemoveFile element has no Name or LongName attribute.
DeprecatedLocalizationVariablePrefix Displayed when a localization variable begins with the deprecated ‘$’ character.
NamespaceChanged Displayed when the namespace of an element has changed.
UpgradeVersionPropertyAttributeRequired Displayed when an UpgradeVersion element is missing the required Property attribute.
UpgradePropertyChild Displayed when an Upgrade element contains a deprecated Property child element.
RegistryElementDeprecated Displayed when a deprecated Registry element is found.
PatchSequenceSupersedeTypeChanged Displayed when a PatchSequence/@Supersede attribute contains a deprecated integer value.
PatchSequenceTargetDeprecated Displayed when a deprecated PatchSequence/@Target attribute is found.
VerbTargetDeprecated Displayed when a deprecated Verb/@Target attribute is found.
ProgIdIconFormatted Displayed when a ProgId/@Icon attribute value contains a formatted string.
IgnoreModularizationDeprecated Displayed when a deprecated IgnoreModularization element is found.
PackageCompressedIllegal Displayed when a Package/@Compressed attribute is found under a Module element.
PackagePlatformsDeprecated Displayed when a Package/@Platforms attribute is found.
ModuleGuidDeprecated Displayed when a deprecated Module/@Guid attribute is found.
GuidWildcardDeprecated Displayed when a deprecated guid wildcard value is found.
FragmentRefIllegal Displayed when a FragmentRef Element is found.
FileRedundantNames Displayed when a File/@Name matches a File/@ShortName.
Posted in WiX at March 26th, 2008. 4 Comments.

A common request on wix-users is how to create shortcuts to a Web site. MSI’s Shortcut table and CreateShortcuts action don’t support targets that point to URLs like http://www.joyofsetup.com/. A shortcut’s target can point only to a feature (for advertised shortcuts) or a file or directory (for unadvertised shortcuts).

You can fake a shortcut to a URL by using the IniFile table to create a .url file. It’s a bit of a hack, given that the format of .url files isn’t explicitly documented and is therefore subject to change. (Granted, it’s not likely to change, because that would break a lot of existing applications.)

I needed URL shortcuts for Train Simulator so I wrote a custom action to create them. I then added authoring support to the WixUtilExtension compiler extension. With reviews from Heath and Peter, I checked in the work today. You’ll see it in the next weekly build of WiX v3.

The authoring is similar to, but simpler than, a standard shortcut. Here’s the attribute schema reference from WiX.chm:

Name Type Description Required
Id String Unique identifier in your installation package for this Internet shortcut. Yes
Directory String Identifier of the directory where the shortcut should be created. Yes
Name String The name of the shortcut file, which is visible to the user. (The .lnk extension is added automatically and by default, is not shown to the user.) Yes
Target String URL that should be opened when the user selects the shortcut. Windows opens the URL in the appropriate handler for the protocol specified in the URL. Note that this is a formatted field, so you can use [#fileId] syntax to refer to a file being installed (using the file: protocol). Yes

Here’s what a simple http shortcut looks like:

<util:InternetShortcut
Id=”Home”
Directory=”DesktopFolder”
Name=”Joy of Setup”
Target=”http://joyofsetup.com” />

You can also create shortcuts to resources using non-http protocols:

<util:InternetShortcut
Id=”ARP”
Directory=”ProgramMenuFolder”
Name=”ARP”
Target=”file://[%WINDIR]\Help\addremov.chm” />

Internet shortcuts are needed, among other reasons, for Vista’s Game Explorer. More on that in a future entry.

Posted in Flight Simulator, WiX at March 18th, 2008. 11 Comments.

WiX v3.0.3907.0 was released on Friday, 7-Mar-08. You can download it from http://wix.sourceforge.net/releases/3.0.3907.0/.

New features

  • In last week’s build, I updated the .cubs to the versions shipped in the Windows 2008/.NET Framework 3.5 SDK. While that fixed the bugs in ICE39 and ICE45, it introduced a new bug — or at least a “suboptimal design” — in ICE66. ICE66 reports a warning if you use a Shortcut table that has the new columns introduced in MSI 4.0. WiX supports MSI 4.0, so includes those columns. (Previous versions of MSI ignore them.)
    Unfortunately, ICE66 checks only that the columns are present and that your package schema is less than 400. It should check that any of the columns are used (i.e., have non-NULL values) before warning. So I worked around ICE66 by implementing all of its checks in the WiX linker instead and suppressing ICE66.
    It’s easy to implement such checks in the linker because we have all the WiX objects to check various tables and rows; it would be interesting to see if we could implement the less efficient ICEs (like ICE03) in the linker and cut down on build time.

Bug fixes

  • 1906436
  • 1909111
  • WoW64 file system redirection is now enabled while creating the MSXML object, to fix the XmlFile and XmlConfig custom actions on Vista x64.
  • Peter, who originally added support for InstanceTransforms, added support for transforms when the Product/Id attribute uses asterisk to generate the product code every build. That was previously an error.
Posted in WiX at March 9th, 2008. 9 Comments.

WiX v3.0.3829.0 was released on Friday, 29-Feb-08. You can download it from http://wix.sourceforge.net/releases/3.0.3829.0/.

New features

  • Rob brought back the long-lost WixComPlusExtension and WixMsmqExtension extensions, both in the binaries .zip and the WiX installer package.
  • WiX extensions can now have reference paths specified as metadata in .wixproj projects.
  • You can now run individual ICEs during validation (in addition to the default of running all except those explicitly suppressed). Light has a -ice switch and an Ices property in the MSBuild targets.
  • XmlFile in WixUtilExtension now supports a SelectionLanguage attribute to choose between XPath and XSLPattern if MSXML 3.0 or later is installed on the target machine.
  • Heath added support for extensions to be able to support version-checking between authoring and extension version. So you can make sure your authoring is being built with a version of the extension that handles it correctly (or, say, has an important bug fix).

Bug fixes

Posted in WiX at March 2nd, 2008. 3 Comments.