How did the bits go, again? Compiling your .NET applications for 32-bit and 64-bit systems
Posted: (EET/GMT+2)
64-bit PC computers have existed for years, but the fact is that most users still work with 32-bit systems, and we have to wait a couple of years for the doubling of bits to become mainstream. Personally, I believe that ordinary people will first notice that they need a 64-bit system once they start needing more than 4 GB of memory, but that's a topic for another post.
Now, as a .NET developer, you are quite effectively guarded from the number of bits in the operating system and the processor. But even so, you must know how to detect the “bitness" of the operating system under which your application is running. Similarly, you have to be aware of the options of compiling your applications for 32-bit and 64-bit platforms.
The first thing to remember is that a regular 32-bit Windows system cannot run 64-bit applications, but a 64-bit Windows can run both 32-bit and 64-bit applications. Now, if you compile your C# application with Visual Studio by default, it will function as a 32-bit application on a 32-bit Windows box, and as a 64-bit application on a 64-bit application.
However, you can also control the number of bits your application supports. In Visual Studio's project properties, you can find a setting called “Platform target" under the Build tab:

The default value for this setting is “Any CPU", which works as described above. By selecting “x86", you can force your application to always be a 32-bit application, or by selecting “x64", to always be a 64-bit application. Of course, if you compile your application to be a 64-bit application and you try to run it on a 32-bit operating system, the results can be like this:

In text, the error message says:
The version of this file is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need an x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher.
As you can see, the Platform target setting in Visual Studio is pretty straightforward and easy to understand. But how would you detect the current platform in your code, and the specified platform target in code? Luckily, this is quite easy as well, and I'll share some code as well.
Firstly, you might want to detect the bit depth of the current operating system. As you might guess, there are multiple ways to do that, but one of the simplest ways to do this check is to see if the registry key “HKEY_LOCAL_MACHINE\Software\Wow6432Node" exists. If it does, it's pretty good indication the system is (recent) a 64-bit Windows. Here's the quick C# code to detect this:
using Microsoft.Win32;
...
StringBuilder builder = new StringBuilder();
builder.Append("Wow64 key: Does ");
RegistryKey wow64Key = Registry.LocalMachine.OpenSubKey(
"Software\\Wow6432Node", false);
if (wow64Key == null) builder.Append("NOT ");
else wow64Key.Close();
builder.AppendLine("exist");
MessageBox.Show(builder.ToString());
Then, how could you detect the chosen number of bits of your executable? If we again take the straightforward route, then checking the size of the IntPtr structure works well and is fast. If the size is 4 bytes, then you are running your code in a 32-bit application and if 8, then it's a 64-bit application:
builder.AppendLine("IntPtr size: " + IntPtr.Size.ToString());
If you want more proof, then Windows API supports a function called IsWow64Process. The problem with this function is, however, that it requires Windows XP SP2 or Windows Server 2003 at least. This function returns true if your application is running in WOW64 mode (WOW64 stands for “Windows On Windows 64" and allows 32-bit applications to run on a 64-bit operating system) and false if not. So, if you specify your application to be a 32-bit application with the Platform target setting set to “x86" and then run your application on a 64-bit computer, then IsWow64Process will return true.
Here's a short C# code snippet to show how you can use the API function:
using System.Runtime.InteropServices;
using System.Diagnostics;
...
[DllImport("kernel32.dll", SetLastError = true,
CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process(
[In] IntPtr hProcess,
[Out] out bool wow64Process);
...
Process p = Process.GetCurrentProcess();
IntPtr handle = p.Handle;
bool isWow64 = false;
if (IsWow64Process(handle, out isWow64))
{
builder.AppendLine("IsWow64Process: " +
(isWow64 ? "Yes" : "No"));
}
else
{
builder.AppendLine("IsWow64Process: Call failed");
}
I compiled the following table to help you see how this works in practice:
| Windows OS bits | Platform target setting (application bits) | IntPtr.Size | IsWow64Process return value |
| 32-bit | Any CPU | 4 | false |
| 32-bit | x86 | 4 | false |
| 32-bit | x64 | (app won't run) | (app won't run) |
| 64-bit | Any CPU | 8 | false |
| 64-bit | x86 | 4 | true |
| 64-bit | x64 | 8 | false |
Remember, the tips shown here to check the "bitness" might not be the official ones, but work reasonably well most of the time.
Good luck!
Keywords: Visual Studio Platform Target, 32-bit and 64-bit applications, how to detect number of bits in the operating system, how to check is operating system is 64-bit.