x64 Development with .NET

Posted November 13, 2007 1:01 AM Categories: .NET | x64

Earlier this year I made the switch to a 64-bit operating system - Vista Ultimate x64 to be exact.  For the most part, this process has been relatively painless, but there have been a few hiccups along the way (x64 compatible drivers, mainly, but that's not the point of this discussion).

In the world of x64 development, there have been a few struggling points that I thought I'd outline here.  This list will likely grow, so expect future posts on the matter.

In the wonderful world of .NET development, applications and assemblies can be compiled to target various platforms.  By default, applications and assemblies are compiled as Any CPU in Visual Studio.  In this scenario, the CLR will load the assembly as whatever the default target is for the machine it is being executed on.  For example, when running an executable on an x64 machine, it will be run as a 64-bit process.

Visual Studio also provides for 3 specific platform targets:  x86, x64 and Itanium (IA-64).  When building an executable as a specific target, it will be loaded as a process of that type.  For example, an x86-targeted executable run on an x64 machine will run as a 32-bit process using the 32-bit CLR and WOW64 layer.  When assemblies are loaded at runtime, they can only be loaded by a process if their target matches that of the hosting process, or it is compiled as Any CPU.  For example, if x64 were set as the target for an assembly, it can only be loaded by an x64 process.

This has come into play in a few scenarios for me:

  • XNA - XNA is available as a set of 32-bit assemblies only.  Therefore, when referencing the XNA assemblies, the executable/assembly using them must be targeted to the x86 platform.  If it is targeted as x64 (or as Any CPU and run on a 64-bit machine), an error will be thrown when trying to load the XNA assemblies.
  • Microsoft Robotics Studio - The XInputGamepadService uses XNA internally to talk to the Xbox 360 controller.  See above.
  • Managed DirectX - While this is already deprecated and being replaced with XNA, it still has its uses.  The assemblies are not marked for a specific target, however I had difficulty with memory exceptions, especially with the Microsoft.DirectX.AudioVideoPlayback assembly.
  • Phidgets - Depending on what library you download and when, it may or may not be marked as 32-bit only.  The current version (11/8/07) is marked as such, and so requires a 32-bit process to host it.

The easiest way to determine if an executable or assembly is targeted to a specific platform is to use the corflags application.  To use this, open a Visual Studio Command Prompt from your Start menu and run it against the assembly you wish to check.

image

Here's a handy table to decode the resulting information:

CLR Header NOT the version of the CLR the file is compiled for
2.0 = .NET 1.0 or 1.1
2.5 = .NET 2.0
PE PE header type
PE32 = 32-bit
PE32+ = 64-bit
CorFlags Various flags for endian type, ILONLY, etc.
ILONLY The file contains IL only (i.e. no unsafe code)
32BIT 1 = x86 target
0 = Any CPU target
Signed 1 = Assembly signed
0 = Assembly not signed

And here is a second table showing the mapping from target to flags:

Any CPU PE32 with 32BIT = 0
x86 PE32 with 32BIT = 1
x64/Itanium (IA-64) PE32+ with 32BIT = 0

So how do you work around using 32-bit assemblies on a 64-bit platform?  There are two answers to this.

Use corflags against the file with the /32BIT- switch to remove the x86 restriction.  This will make the assembly look like an "Any CPU" compilation.  Note that this will only work on unsigned assemblies.  If the assembly is signed, you can use the /Force switch to make the change, but this will likely just break the assembly and make it unusable.  I don't personally recommend using corflags since it's likely that if an assembly is distributed with this flag set, it's probably done that way for a reason.  So, let's look at method two.

Create a new configuration which targets x86 and everything should work.  With the host process being forced to run as a 32-bit application, any 32-bit specific libraries will work just fine.  Here's how:

  1. From the Build menu, select Configuration Manager
  2. In the Active solution platform: drop down, select <New...>
    image
  3. In the Type or select new platform drop down, select x86
    image
  4. Click OK to get back to the main Visual Studio window and ensure the x86 configuration is selected in the build bar or in the Platform drop down in the project settings.
    image
  5. Rebuild the project

Your output will now be located in the bin\x86 directory.

In the next installment, I'll discuss some of the issues with using P/Invoke in .NET from the 64-bit world.

Comments (12) -

MJ
3/31/2009 6:20:20 PM #

oh my god, thank you so much for this.  i could NOT get a program running on vista/VS2008 and could NOT figure out why - this was magical and such a savior - THANK YOU SO MUCH

Reply

Robb
7/22/2009 10:40:51 AM #

Thank you.
A program was not working on my WIndowsXP x64 and I downloaded the SDK, and I ran corflags (forced 32bit) and voula Laughing

I am so grateful to you for this tip!

Reply

Ted
8/2/2009 5:22:50 AM #

I had the same problem, so I changed the target platform as described by T0n0. But, as soon as I specified a platform (x86) some namespaces/libraries/DLLs suddenly "could not be found".

Im using MySql connector, and that works without any problems if I use "Any CPU", but if I set it to either x86 or x64 then I get this:

The type or namespace name 'MySql' could not be found (are you missing a using directive or an assembly reference?)

There are other DLLs that get the same error - it is NOT only MySql.
Any ideas on that?

Reply

Arun Mahendrakar
11/12/2009 2:00:36 PM #

Brian, awesome article.. thnx a bunch.

Ted, I'm guessing this. Did you just copy the MySql assemblies to the bin folder or have you actually referenced them in the project? If it is the former, then the bin folder path anything other than 'Any CPU' is different (look at the folder structure of your app). You might have to copy them the the correct bin folder.

Reply

Marco
4/1/2010 7:03:44 AM #

You say "With the host process being forced to run as a 32-bit application". What happens if my host process needs to run a 32bit app and a 64bit app? Is this a supported scenario?

Thanks,
Marco

Reply

Brian Peek
4/1/2010 9:51:31 AM #

@Marco, that is not supported.  Whatever your host process runs as is what everything under it must run as.

Reply

Prathima K
4/8/2010 2:46:41 PM #

Thanks a lot Brian. This worked just like that. Awsome!!!

Reply

Don bouie
3/18/2011 8:05:33 PM #

I'm a beginner that's developing on  a64 bit, 2010 Visual Studio Express. Will
my programs run on a 32bit machine. There have been some Win32 errors.
On my 32bit XP machine, but everything is fine on the 64bit Machine. In 2010
Visual Expess there is no Build configuration that  I can see.

Reply

Sumit India
9/6/2011 9:24:38 PM #

Actually I have four projects in a solution but I am able to create new configration for x64 for three projects but for the last one I am unable to create new configration foe x64(this is the dotfuscator project) even if I am following the same steps you have told.

Reply

Brian Peek United States
9/6/2011 9:27:51 PM #

@Sumit, not every project type supports an x64 build type.

Reply

Keyur India
10/15/2011 2:47:11 AM #

Hello,

I have installed VS2005 & Oracle 10g 64bit Client on windows 2008 R2 64bit Server. But I am getting error message when I access crystal report on client machine.
Error Message : The type initializer for 'CrystalDecisions.CrystalReports.Engine.ReportDocument' threw an exception.
is this the problem related to 64bit on windows 2008. I think it should be. Because in debug mode on server, crystal report working properly. but from published edition, it is raised error. So can you help me to come out from this problem ?

Keyur

Reply

Brian Peek United States
10/15/2011 6:25:43 AM #

I have no experience with Crystal, but that doesn't sound like an x86 vs x64 issue if it works in debug but not when published.

Reply

Add comment