64-bit Applications and .Net Platform

All applications built with the 1.0 and 1.1 releases of the .NET Framework are treated as 32-bit applicationsand are always executed under WOW64 on the 32-bit common language runtime (CLR) on a 64-bit operating system. In addition, 32-bit specific applications built with version 2.0 of the .NET Framework would run under WOW64 on 64-bit platforms.

With the introduction of Win64 (64-bit versions of Windows), PE files (EXEs and DLLs) can be marked either as 32-bit OR 64-bit. When a 32-bit EXE is launched on Win64, it runs in "the WOW" (Windows-32 on Windows-64) to present an illusion of a 32-bit operating system to the process. Generally only 32-bit DLLs can be loaded into a 32-bit process, and only 64-bit DLLs can be loaded into a 64-bit process. CLR added 64-bit support in version 2.0. Since people want to write .NET libraries that they could re-use from both 32-bit and 64-bit processes, OS loader was extended to support to enable architecture-neutral ("AnyCPU") PE files.

Managed architecture-neutral DLLs are fairly straight-forward - they can be loaded into either 32-bit or 64-bit processes, and the (32-bit or 64-bit) CLR in the process will do the right thing with them. AnyCPU EXEs are a little more complicated since the OS loader needs to decide how to initialze the process. On 64-bit OSes they are run as 64-bit processes (unless the 'ldr64' master OS switch says otherwise), and on 32-bit OSes they are run as 32-bit processes. In Visual Studio 2008, AnyCPU is the default platform for C# and VB projects. This means that by default("AnyCPU"), applications you compile will run in 64-bit processes on 64-bit OSes and 32-bit processes on 32-bit OSes.

If you have 100% type safe managed code then you really can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR.

But more than likely the managed application will be involved with any or all of the following:

  • Invoking platform APIs via p/invoke
  • Invoking COM objects
  • Making use of unsafe code
  • Using marshaling as a mechanism for sharing information
  • Using serialization as a way of persisting state

Regardless of which of these things your application is doing it is going to be important to do your homework and investigate what your code is doing and what dependencies you have. Once you do this homework you will have to look at your choices to do any or all of the following:

  • Migrate the code with no changes.
  • Make changes to your code to handle 64-bit pointers correctly.
  • Work with other vendors, etc., to provide 64-bit versions of their products.
  • Make changes to your logic to handle marshaling and/or serialization.

Migration considerations

When migrating managed applications that use p/invoke, consider the following items:

  • Availability of a 64-bit version of the DLL
  • Use of data types

The following is a discussion of the different considerations that must be given to making use of COM interoperability where managed code makes COM calls in a 64-bit environment:

  • Availability of a 64-bit version of the DLL
  • Use of data types
  • Type libraries

Find your Application Bitness at runtime

There area also managed library functions to assist you at runtime to determine what environment you are running in.

  • System.IntPtr.Size - to determine if you are running in 32-bit or 64-bit mode
  • System.Reflection.Module.GetPEKind - to programmatically query an .exe or .dll to see if it is meant to run only on a specific platform or under WOW64

Determining the status of an .exe or .dll

Use corflags.exe at the command line to see if it an .exe or .dll is meant to run only on a specific platform or under WOW64. You can also use corflags.exe to change the platform status of an .exe or .dll. See CorFlags Conversion Tool (CorFlags.exe) for more information. A Visual Studio 2005 assembly's CLR header (or COM+ Runtime header) has the Major Run-time Version Number set to 2 and the Minor Run-time Version Number set to 5. In Visual Studio 2003 assemblies, they are 2 and 0, respectively. All applications that have the minor runtime version set to 0 are treated as legacy applications and are always executed under WOW64 on 64-bit machines.

Use the GetPEKind to programmatically query an .exe or .dll to see if it is meant to run only on a specific platform or under WOW64.

ref:

64bit .Net -

http://msdn.microsoft.com/en-us/library/ms241064(VS.80).aspx

http://blogs.msdn.com/joshwil/archive/2005/05/06/415191.aspx

Migrating 32-bit Managed Code to 64-bit -

http://msdn.microsoft.com/en-us/library/ms973190.aspx

AnyCPU Exes are usually more trouble than they're worth -

http://blogs.msdn.com/rmbyers/archive/2009/06/08/anycpu-exes-are-usually-more-trouble-then-they-re-worth.aspx