I would like to keep my top level .wxs DRY while building 32 and 64 bit installers. I am using the -arch argument to candle.exe to control what default installer architecture is getting built.
The wall I am hitting right now is that it appears the ProgramFilesFolder is different between 32 and 64bit (ProgramFiles64Folder) architectures. Here is my first attempt to work around:
<?if $(sys.BUILDARCH)=x64 ?>
<Directory Id='ProgramFiles64Folder' Name='PFiles'>
<?else ?>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<?endif ?>
<Directory Id='the-rest' Name="Company Name">
...
I tried this with an error. Apparently the XML validation is fired before the preprocessor is evaluated. When I manually change to use ProgramFiles64Folder my build works.
I tried to go down the DirectoryRef route without success. Any suggestions on getting this to work without doing a sed replace within the .wxs file?
Note: I tried this in Wix 3.5 and 3.6.
Rather than conditionally including the opening Directory
elements (which invalidates the XML), conditionally set preprocessor variables which are used as directory names, as @Daniel Pratt's comment refers to. Similarly, having a "yes/no" variable conditioned on platform makes it easy to set up 64 bit components, registry searches, etc.
(From this answer)
<?if $(var.Platform) = x64 ?>
<?define ProductName = "Product Name (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
<?define ProductName = "Product Name" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>
$(var.Platform)
is built-in, but its value is used to define custom variables $(var.ProductName)
, $(var.Win64)
and $(var.PlatformProgramFilesFolder)
.
You can either use preprocessor <?if
directives to test variables' values (as is done with $(var.Platform)
when defining the custom variables above) or have the preprocessor insert variables' values into XML attribute or element values. Couple of examples:
<Component Id="..." Win64="$(var.Win64)">
...
</Component>
This will produce warnings in the Visual Studio WiX editor about $(var.Win64)
not being one of the allowable attribute values (yes
/no
) but these can be safely ignored, because the preprocessor will have substituted an appropriate value by the time the compiler gets hold of it.
<Directory Id="$(var.PlatformProgramFilesFolder)">
...
</Directory>
In response to rharrison33's comment asking how to handle the requirement for different product codes (or pretty much anything) in the 32 and 64 bit installers (assuming you can't/don't want to auto-generate them):
candle <all other flags> -d ProductCode32=<guid1> -d ProductCode64=<guid2>
<?if ?>
branch: <?define ProductCode = "$(var.ProductCode32)" ?>
<?if ?>
branch: <?define ProductCode = "$(var.ProductCode64)" ?>
$(var.ProductCode)
in Product/@Id
.Made this CW because Daniel's link answers the question and has a lot more great info besides.