
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:
- Create a new setup project and call it
SixtyFourBitInstaller
. - 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: - 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(); } } }
- 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:
- Right-click on the setup project in Solution Explorer and go to Properties | Tool Settings. Then, in the Compiler textbox, add
-arch x64
: - Replace the existing directory structure in
Product.wxs
with the following code, making sure to useProgramFiles64Folder
instead ofProgramFilesFolder
:<Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFiles64Folder"> <Directory Id="INSTALLFOLDER" Name="My Software" /> </Directory> </Directory>
- Add a
Component
andFile
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>
- Run the installer and then check that
ConsoleApp64Bits.exe
was installed inC:\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
.