Thursday, October 12, 2006

Running .NET 2.0 applications under 64-bit Windows (x64)

By default Visual Studio 2005 compiles .NET executables under "Any CPU" compilation target (the exception is C++/CLI where you have to choose 32-bit or 64-bit target). This allows the same binaries to run as 32-bit or 64-bit binaries depending on the operating system .NET framework is running on. However, if your executable compiled thus depends on 32-bit components (either .NET 1.1 assemblies, 32-bit native DLLs, C++/CLI .NET 2.0 assemblies under 32-bit target, etc.) it will crash when run on 64-bit operating system (and vice versa; if it depends on 64-bit native DLL for example it will crash on 32-bit operating system - but that's not the usual case.) The reason for this is that in Windows 64-bit processes cannot load 32-bit components and vice versa. So what can be done about this?

There are several ways to solve this:
1. Compile all your binaries under "32-bit" target in VS2005. This is the easiest thing to do but it prevents .NET framework from optimizing your code (on the fly of course) to utilize fully 64-bit CPUs. Also, if you are developing assemblies that need to be run in 64-bit processes then this option is out.
2. Convert all 32-bit dependencies to "Any CPU" dependencies. Depending on your situation this can range from easy to impossible to do (e.g. if you are using 3rd party 32-bit native DLLs, it won't help to ask the vendor to recompile for 64-bit or even for .NET - you will need to find a .NET 2.0 library compiled as "Any CPU" to do the same job)
3. Obtain all dependencies as 32-bit and 64-bit versions and install them accordingly. This can also range from easy to impossible to do (e.g. you are using 32-bit native DLLs from a now defunct closed source vendor) but it does allow you to run both managed and native code, if you have such, as fully 64-bit.
4. Move all 32-bit dependencies to a separate 32-bit executable and communicate with it from your 64-bit process through some form of IPC (e.g. shared memory). Yet again this can range from simple to impossible to do (e.g. using 32-bit components in GUI would be a tough to implement through any IPC) But it's a great solution when you are using critical 32-bit components whitout any chance on getting them as 64-bit components. Variant of this solution is out-of-process COM library.

Now that I'm thinking about it, we at ApexSQL in our efforts to bring 64-bit support in all our apps, had the opportunity to implement all four solutions at one time or another. Please feel free to comment on these - I must have missed some alternative solution. I would be most interested in hearing other experiences.

Finally, for those that need to support users running their "Any CPU" applications dependent on 32-bit components on 64-bit operating systems (that's a mouthful!) I recommend reading this article: Setting Platform dependency bits in .Net 2.0. It shows how to use a utility from .NET 2.0 SDK to force application to always run as a 32-bit process.


Anonymous said...

i want to run my 32 bit windows application Under 64 bit Win Vista OS, so i have gone through your article, but i didnt find any solution for that, so can you pls tell me, what exactly i have do to fullfill my requirements.

Thanks in Advance.........

Ivan Erceg said...

Could you tell me what seems to be the problem? 32-bit Windows applications should just work on any 64-bit Windows OS.

mrosso said...

I have a 32-bit app that depends on .net framework to run. If it run it on a 64-bit Win7, it crashes since I have to run a 64-bit .net framework. The thing is, the 32-bit app doesnt see the 64-bit .net framework as something it can use to run. therefore, I get exception errors. What can i do to get this 32-bit app to run on a 64-bit os when .net is needed.


Ivan Erceg said...

Mike, are you sure that's the problem? Have you check the loading issues with Fusion Viewer from .NET SDK?