I previously posted an example that allows you to build a WiX-based MSI that will install a Windows Vista Media Center application and create a custom start menu strip. However, there is a limitation in this example (that was pointed out in this post on the Media Center Sandbox discussion forum) that affects the ability to install the application on 64-bit operating systems. This blog post describes the limitations in my previous sample and presents a modified version of that sample that will allow you to build both 32-bit and 64-bit MSIs in order to work around the limitations.
Description of the problem with my previous example
As this forum post describes, you have to directly set registry entries in order to add custom strips to the Media Center start menu (which means that you have to author RegistryKey and RegistryValue elements in WiX). However, if you create a 32-bit MSI and then try to install it on a 64-bit OS, the registry entries will get written to the WOW64 hive (HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft). The 64-bit version of Windows Vista Media Center looks in the 64-bit registry hive and not the WOW64 registry hive when looking for custom start menu strips to load. Therefore, the custom start menu strip will not appear in the Media Center start menu on a 64-bit OS in my previous example.
Example that can be used to solve this problem
To solve this issue, it is necessary to create separate 32-bit and 64-bit installers. It is a little bit tricky to configure all of the settings and attributes that are necessary to create a 64-bit MSI just by reading through WiX and Windows Installer documentation, so I decided to create a WiX 3.0-based example that can be used to build 32-bit and 64-bit MSIs from the same WiX source (WXS) file.
You can download this example from http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/start%7C_menu%7C_strip%7C_setup%7C_example%7C_with%7C_64bit.zip. I started from my previous 32-bit-only example, and added 64-bit build support. While this sample happens to install a Windows Vista Media Center application, it is intended to help demonstrate the general concepts required to create 64-bit MSIs in WiX.
Changes made in this example to enable 64-bit builds
The new sample includes a single WXS file that is processed twice in order to build 2 different MSIs (one 32-bit and one 64-bit). In order to create a single WXS file that can build both types of MSI, I introduced a WiX pre-processor variable to pass in the name of the processor architecture, and then I added some if/then/else blocks to conditionally set some of the necessary MSI attributes based on whether the MSI being created will be 32-bit or 64-bit.
If you look in the setup.wxs file in the example I posted, you can see all of the changes that I made to enable building a 64-bit MSI by looking for sections of the file that are enclosed in if statements such as the following:
<?if $(var.ProcessorArchitecture)=x64 ?>
<Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" Platforms="x64" />
<Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" />
In order to set the ProcessorArchitecture variable, I added the following command line parameter when calling candle.exe to compile the WXS file:
"%WIX_BUILD_LOCATION%\candle.exe" setup.wxs -dProcessorArchitecture=%PROCARCH% -out "setup_%PROCARCH%.wixobj"
In addition, I added a second set of commands to call candle.exe and light.exe twice - one with the ProcessorArchitecture value set to x86 and the other with the ProcessorArchitecture value set to x64.
Specific differences between a 32-bit MSI and a 64-bit MSI
The following are the changes that I made in order to be able to create both 32-bit and 64-bit MSIs in WiX:
- I created a unique product code for the x64 MSI that is different from the x86 MSI
- In the Package element, the Platforms attribute must be set to the proper 64-bit operating system so that Windows Installer will recognize it as a 64-bit MSI. In my example, I am creating an x64 MSI, so I set the Platforms value to "x64" for the 64-bit MSI, and left it blank (the default value) for the 32-bit MSI
- I created a different default directory structure for each processor architecture. The 64-bit MSI will install under the ProgramFiles64Folder and the 32-bit MSI will install under the ProgramFilesFolder by default. This is necessary because Windows Installer requires 64-bit components to install under a 64-bit directory by default
- I created a unique set of 64-bit components by copying the original set of 32-bit components, updating the Id values to be different than the 32-bit Id values, creating unique Guid values and adding the element Win64="yes" to indicate that these components are 64-bit. A component must be marked as Win64="yes" in order to cause registry entries to be written under the 64-bit registry hive instead of the WOW64 registry hive
- In order to prevent the 32-bit MSI from installing on a 64-bit OS (which will work by default, but that we do not want to work once we have a specific 64-bit MSI to install on a 64-bit OS), I added a custom action to the 32-bit MSI and scheduled it in the InstallExecuteSequence and InstallUiSequence tables. The custom action checks to see if the Windows Installer 64-bit property is set (which indicates that the MSI is being invoked on a 64-bit system), and if that is set, it will block the MSI from installing
Where to read more about 64-bit issues related to Windows Installer
When working on this example, I relied heavily on the information in this post on Heath Stewart's blog and the links to Windows Installer MSDN topics that are included in it. If you are looking for more detailed information about how Windows Installer works behind the scenes in 64-bit scenarios, I encourage you to check out this blog post and also the other topics in Heath's 64-bit blog category.
<update date="3/23/2009"> Fixed broken link to sample download location. </update>