Say I have 2 Winform projects A, B.
Project A (target .NET 2.0) has to be run on x86 (it is an external library) and for legacy reasons project B (target .NET 4.0) has to be run on Any CPU. Now I need to call A's methods from project B but it throws an error:
"An unhandled exception of type 'System.BadImageFormatException' occurred in System.Windows.Forms.dll"
Additional information: Could not load file or assembly 'CSharpDemo, Version=1.0.5414.18636, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format."
However, I found if I target project B on .NET 4.5 then this problem doesn't occur. But I still want Project B to be targeting 4.0, how to achieve this?
If any of your code calls 32-bit x86 libraries, the entire process needs to load as x86. No exceptions.
To do this, set the EXE project to x86, set DLL projects that have native x86 dependencies to x86, and for pure managed DLL projects you can use AnyCPU -- .NET will load them as x86 for your x86 EXE, but they can also load into x64 EXEs.
Remember that x86 code runs just fine on x64 processors running x64 Windows, with the help of the WOW64 compatibility layer.
(with limited exceptions: on Windows Server edition, WOW64 is an optional component, and in the preinstall environment there is no WOW64).
You may find the answer to your question in following blog post
http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/
Here is summary
.net 4.0
What AnyCPU used to mean up to .NET 4.0 (and Visual Studio 2010) is the following:
•If the process runs on a 32-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
•If the process runs on a 64-bit Windows system, it runs as a 64-bit process. IL is compiled to x64 machine code.
•If the process runs on an Itanium Windows system (has anyone got one? ;-) ), it runs as a 64-bit process. IL is compiled to Itanium machine code.
.net 4.5
In .NET 4.5 and Visual Studio 11 the cheese has been moved. The
default for most .NET projects is again AnyCPU, but there is more than
one meaning to AnyCPU now. There is an additional sub-type of AnyCPU,
“Any CPU 32-bit preferred”, which is the new default (overall, there
are now five options for the /platform C# compiler switch: x86,
Itanium, x64, anycpu, and anycpu32bitpreferred). When using that
flavor of AnyCPU, the semantics are the following:
•If the process
runs on a 32-bit Windows system, it runs as a 32-bit process. IL is
compiled to x86 machine code.
•If the process runs on a 64-bit Windows
system, it runs as a 32-bit process. IL is compiled to x86 machine
code.
•If the process runs on an ARM Windows system, it runs as a
32-bit process. IL is compiled to ARM machine code.