The effects of x64 on your .Net application

When you run an application created using .Net 2.0 or later on an x64 version of Windows, it will execute as a native 64 bit application. This is generally a good thing; your application gets to use the larger virtual address space and other advantages of x64 without you needing to change anything.

There are however a few consequences of running as a 64 bit process which need to be understood. There are three main differences when your application is running as a 64 bit process:

  1. You cannot use 32 bit DLLs.
  2. File and registry virtualization is always disabled.
  3. DEP is always enabled.

The first issue is relatively well known. A 64 bit process cannot load 32 bit DLLs, and .Net is no exception. This isn’t a problem if you use PInvoke to use native Windows APIs; all the Windows DLLs come in both 32 and 64 bit versions. But if you’re using a third party (or your own) native DLL or COM component, you need to be aware of this. Also some .Net libraries, such as Managed DirectX and XNA, indirectly depend on 32 bit DLLs and will therefore not work in a 64 bit process. If you try to run such an application on Windows x64, it will crash with a BadImageFormatException.

If your application depends on any external native DLLs and you cannot provide a 64 bit version of those DLLs, or if the application is otherwise incompatible with x64, you should change the target CPU of your executable to x86. For C# projects in Visual Studio 2008, you can find this setting on the “Build” tab of the project properties; the “Platform target” setting is the one you want. For Visual Basic projects, look under the “Compile” tab, click the “Advanced Compile Options…” button, and change the “Target CPU” setting. When you change this setting, the compiler adds an attribute to the executable to tell the CLR to always run the program as a 32 bit process. You can also set this setting to x64 or ia64 which means your application will fail to run on systems that don’t support those architectures.

The second issue is less well known, and it applies to Windows Vista and newer only. If you have UAC enabled your application will run with limited rights, and cannot write to many locations such as Program Files or HKEY_LOCAL_MACHINE in the registry. For compatibility, Windows will redirect attempts to write to these locations to a different folder in the user’s profile (in %LocalAppData%\VirtualStore, to be precise). For 32 bit processes, this behaviour is enabled by default (you can manually disable it using a manifest), but for 64 bit processes, it is always disabled (it cannot be enabled at all) so if you attempt to write to these locations, it will fail.

File and registry virtualisation can be disabled for 32 bit processes using a manifest, and to make your application behave consistently on both 32 and 64 bit systems I strongly recommend you do this. Visual Studio 2008 will automatically embed a manifest in your application that disables the virtualisation. If you are using Visual Studio 2005, you can use this method to embed the manifest.

The final issue has to do with Data Execution Prevention. XP and Vista will not apply DEP protection to a 32 bit process unless the executable is marked with the NXCOMPAT flag, but for 64 bit processes, DEP is always enabled. If you interop with native code which might be incompatible with DEP you need to be aware of this. Visual Studio 2008 (and Visual Studio 2005 as well, provided you’re using .Net 2.0 SP1) will mark the application with the NXCOMPAT flag so DEP will be enabled for 32 bit processes as well. If your application is not compatible with DEP, and you cannot fix it for some reason, you must set the platform target to x86 as described above, and remove the NXCOMPAT flag.

Categories: Programming
Posted on: 2009-01-08 12:58 UTC.

Comments

No comments here...

Add comment

Latest posts

Categories

Archive

Syndication

RSS Subscribe