I have a project that builds in 32/64-bit and has corresponding 32/64-bit dependencies. I want to be able to switch configurations and have the correct reference used, but I don't know how to tell Visual Studio to use the architecture-appropriate dependency.
Maybe I'm going about this the wrong way, but I want to be able to switch between x86 and x64 in the configuration dropdown, and have the referenced DLL be the right bitness.
AFAIK, if your project requires references that are 32-bit or 64-bit specific (i.e. COM-interop assemblies), and you have no interest in manually editing the .csproj file, then you'll have to create separate 32-bit and 64-bit projects.
I should note that the following solution is untested, but should work. If you are willing to manually edit the .csproj file, then you should be able to achieve the desired result with a single project. The .csproj file is just an MSBuild script, so for a full reference, look here. Once you open the .csproj file in an editor, locate the
<Reference>
elements. You should be able to split these elements out in to 3 distinct item groups: references that aren't platform specific, x86-specific references, and x64-specific references.Here is an example that assumes your project is configured with target platforms named "x86" and "x64"
Now, when you set your project/solution build configuration to target the x86 or x64 platform, it should include the proper references in each case. Of course, you'll need to play around with the
<Reference>
elements. You could even setup dummy projects where you add the x86 and x64 references, and then just copy the necessary<Reference>
elements from those dummy project files to your "real" project file.Edit 1
Here's a link to the common MSBuild project items, which I accidentally left out from the original post: http://msdn.microsoft.com/en-us/library/bb629388.aspx
I faced the same problem and spent quite a while searching for a decent solution. Most people offer manual editing of Visual Studio solution files, which is quite tedious, error prone and confusing when exploring these edited files in Visual Studio GUI afterwards. When I already gave up, the solution came up itself. It is very similar to what Micke recommends in his answer above.
In account manager I created two separate build targets for x86 and x64 platforms, as usual. Next, I added a reference to x86 assembly to my project. On this point, I believed that the project is configured for x86 build only and will never build for x64 configuration, unless I will make manual editing of it as suggested by Hugo above.
After a while, I eventually forgot the limitation and accidentally started x64 build. Of course, the build failed. But important was the error message I received. Error message told that assembly named exactly as my referenced x86 assembly is missing in the folder intended as x64 build target for my solution.
Having noticed this, I have manually copied proper x64 assembly into this directory. Glory! My x64 build miraculously succeeded with proper assembly found and linked implicitly. It was matter of minutes to modify my solution to set a build target directory for x64 assembly to this folder. After these steps solution builds automatically for both x86 and x64 without any manual editing of MSBuild files.
To sum up:
After completion of these steps your solution will properly build for both x86 and x64 configurations.
This worked for me on Visual Studio 2010 .NET 4.0 C# project. Evidently, this is a sort of undocumented internal behavior of Visual Studio, which might be subject of change in 2012, 2013 and 2015 versions. If somebody will try on other versions, please share your experience.
You can use a condition to an ItemGroup for the dll references in the project file.
This will cause visual studio to recheck the condition and references whenever you change the active configuration.
Just add a condition for each configuration.
Example:
I'm referencing the x86 DLLs, located in e.g. \component\v3_NET4, in my project. Specific DLLs for x86/x64 are located in sub-folders named "x86" and "x64" resp.
Then I'm using a pre-build script that copies apropriate DLLs (x86/x64) into the referenced folder, based on $(PlatformName).
Works for me.
Here is what I've done in a previous project, which will require the manual edition of the .csproj file(s). You also need separate directories for the different binaries, ideally siblings of each other, and with the same name as the platform you are targeting.
After adding a single platform's references to the project, open the .csproj in a text editor. Before the first
<ItemGroup>
element within the<Project>
element, add the following code, which will help determine which platform you're running (and building) on.Then, for your platform specific references, you make changes such as the following:
Note the use of the
$(CurrentPlatform)
property, which we defined above. You could, instead, use conditionals for which assemblies to include for which platform. You could also need to:$(PROCESSOR_ARCHITEW6432)
and$(PROCESSOR_ARCHITECTURE)
with$(Platform)
to consider ONLY the target platform of the projectsI had this written up originally for an internal Wiki at work, however, I've modified it and posted the full process to my blog, if you are interested in the detailed step-by-step instructions.
One .Net build with x86/x64 Dependencies
While all other answers give you a solution to make different Builds according to the platform, I give you an option to only have the "AnyCPU" configuration and make a build that works with your x86 and x64 dlls.
You have to write some plumbing code for this. I could not get this working with app.config. If somebody else knows a way to solve it via app.config I really would like to know.
Resolution of correct x86/x64-dlls at runtime
Steps:
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
Add this postbuild script to your startup project, use and modify the paths of this script sp that it copies all your x86/x64 dlls in corresponding subfolders of your build bin\x86\ bin\x64\
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64
--> When you would start application now, you get an exception that the assembly could not be found.
Register the AssemblyResolve event right at the beginning of your application entry point
withthis method:
Benefits:
Drawbacks: - No errors at compile time when x86/x64 dlls do not match. - You should still run test in both modes!
Optionally create a second executable that is exclusive for x64 architecture with Corflags.exe in postbuild script
Other Variants to try out: - You would not need the AssemblyResolve event handler if you assure otherwise that the dlls get copied in your binary folder at start (Evaluate Process architecture -> move corresponding dlls from x64/x86 to bin folder and back.) - In Installer evaluate architecture and delete binaries for wrong architecture and move the right ones to the bin folder.