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 ® Windows Installer Xml Cop version 3.0.3907.0
Copyright © 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.
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.
|-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:
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.|