WiX Cookbook
上QQ阅读APP看书,第一时间看更新

Installing a 64-bit executable file to Program Files

The 64-bit revolution has come and gone. If you're still writing 32-bit applications, you should make the switch if you can. Modern Windows operating systems have full support for it, but for end users to see the benefits, the software needs to be updated to take advantage. The 64-bit programs have the potential for increased performance, better parallel processing, and improved security. See the Technet article at http://technet.microsoft.com/en-us/library/dd630755%28v=office.12%29.aspx for more information.

Once the decision has been made to convert software to 64 bits, the next step is ensuring it's installed to the correct Program Files folder and that our installer identifies itself as being compatible with the 64-bit architecture. In this recipe, we will build a console application that targets the x64 platform and then include it in an MSI package that supports it.

Getting ready

To prepare for this recipe, perform the following steps:

  1. Create a new setup project and call it SixtyFourBitInstaller.
  2. Within the same solution, add a C# console application project and name it ConsoleApp64Bits. Make sure that it targets .NET 4 or later, since we'll need it for the utility method that checks whether we're running in a 64-bit process. To ensure it will run in a 64-bit process on a 64-bit machine, make sure that Platform target on the Build* tab of the project's properties is set to either x64 or Any CPU:
    Getting ready
  3. Update the application's Program.cs file with the following code:
    using System;
    
    namespace ConsoleApp64Bits
    {
      class Program
      {
        static void Main(string[] args)
        {
          if (Environment.Is64BitProcess)
          {
            Console.WriteLine("Process is 64-bits!");
          }
          else
          {
            Console.WriteLine("Process is NOT 64-bits!");
          }
    
          Console.ReadKey();
        }
      }
    }
  4. Add a reference to the console application in our setup project by right-clicking on the References node in Solution Explorer and going to Add Reference… | Projects | ConsoleApp64Bits | Add | OK.

How to do it…

Set the -arch flag to x64 and then set your files to install to the 64-bit program files:

  1. Right-click on the setup project in Solution Explorer and go to Properties | Tool Settings. Then, in the Compiler textbox, add -arch x64:
    How to do it…
  2. Replace the existing directory structure in Product.wxs with the following code, making sure to use ProgramFiles64Folder instead of ProgramFilesFolder:
    <Fragment>
      <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFiles64Folder">
          <Directory Id="INSTALLFOLDER" Name="My Software" />
        </Directory>
      </Directory>
  3. Add a Component and File element for the 64-bit console application, as shown in the following code:
    <Fragment>
      <ComponentGroup Id="ProductComponents"  
                      Directory="INSTALLFOLDER">
        <Component Id="cmpConsoleApp64BitsEXE" 
                   Guid="{7230A6C1-2920-43A0-B9BA-69E4B0A5450C}">
          <File Source="$(var.ConsoleApp64Bits.TargetDir)ConsoleApp64Bits.exe" />
        </Component>
      </ComponentGroup>
    </Fragment>
  4. Run the installer and then check that ConsoleApp64Bits.exe was installed in C:\Program Files\My Software. Run the application and see that it's running in a 64-bit process.

How it works…

An installer has some metadata in it that tells what platform it's targeting, or more accurately, what platform the files it's installing are targeting. In this example, we are packaging up a 64-bit console application. Therefore, the installer should convey that. That's where the -arch flag comes in. By setting it to x64 in the Compiler settings, we're setting up that metadata.

On 64-bit Windows, there are two program files folders: Program Files for 64-bit software and Program Files (x86) for 32-bit software. In our setup project, we swapped the directory that, by default, has Id of ProgramFilesFolder with one that has Id of ProgramFiles64Folder. As the name implies, this will reference the 64-bit Program Files folder.

The next step was to install our application to this directory. The ComponentGroup element has a Directory attribute to specify which directory to install its child components to. We set it to INSTALLFOLDER and since that folder is a subdirectory of ProgramFiles64Folder, we can be sure that it will install to the 64-bit Program Files.

There's more…

It's possible to include 32-bit executable files in your 64-bit installer and have them installed to Program Files (x86). First, be sure that you've added the Directory elements for both ProgramFilesFolder and ProgramFiles64Folder:

<Directory Id="ProgramFilesFolder">
  <Directory Id=" INSTALLFOLDER_X86" Name="My Software" />
</Directory>
<Directory Id="ProgramFiles64Folder">
  <Directory Id="INSTALLFOLDER" Name="My Software" />
</Directory>

Then, for those components that are meant to be installed to Program Files (x86), set the Win64 attribute on the Component element to no. This alerts the installer that this particular file is not 64-bits.

Here's an example that installs a 32-bit executable to Program Files (x86):

<ComponentGroup Id="My32BitComponents" 
                Directory="INSTALLFOLDER_X86">
  <Component Id="cmpConsoleApp32BitsEXE" 
             Guid="{61F4DDB4-07B9-475C-BE34-07BA619DA86F}" 
 Win64="no">
    <File Source="$(var.ConsoleApp32Bits.TargetDir)ConsoleApp32Bits.exe" />
  </Component>
</ComponentGroup>

We store the 32-bit component in its own ComponentGroup that's separate from our other components. Then, we can use the Directory attribute to install child components to INSTALLFOLDER_X86.