[MSBuild] How to reference an assembly specific to the OS architecture
By Michael DELVA on Wednesday 14 July 2010, 11:58 - Miscellaneous - Permalink
TweetThis article is an english translation of this one.
This article is designed for those who, like me, must deal with 2 versions of a same assembly, depending on you have to work on a 32 or 64 bits OS.
In my case, the faulted assembly is System.Data.SQLite.dll, which allows to use SQLite databases under the .Net framework. Therefore, this assembly exists in 2 flavors: 32 and 64 bits. The problems began to arise when I started to build some unit tests to check the behaviour of my repositories. At the beginning, I was developing on 32 bits PC, referencing the 32 bits assembly, and all was fine. But since then, I work as well on a 32 bits PC as on a 64 bits one, and I always have to delete the reference to the assembly, and replace it with a reference to the assembly with the same bitness as the architecture on which the tests are runned.
Not so great...
But that time is now revolved! And if you encounter the same problem, know that a solution does exist. And here it is...
The key of the success in our case is MSBuild.
To make our life easier, we are going to alter the build process of the projects relying on SQLite, to leave it to MSBuild to copy the correct assembly to the correct place (the Output directory of the project).
To begin, we have to change the content of the csproj file of the project. Either by opening it in a text editor, or in Visual Studio, by right clicking on the project in the solution explorer, and selecting Unload Project, then Edit Project.
What we are going to do first, is to add a new node in the XML, right after the root node named Project:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ISx64Server>false</ISx64Server>
<ISx64Server Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">true</ISx64Server>
</PropertyGroup>
Here, we are defining a new property named ISx64Server, whose default value is false, but which will be true if one of the 2 global variables $(PROCESSOR_ARCHITECTURE) or $(PROCESSOR_ARCHITEW6432) is set to AMD64.
The second and last alteration of the file is now at the bottom. There should be a commented area, with this text inside : To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets
The copy of the correct assembly will happen in the node <Target Name="AfterBuild">:
<Target Name="AfterBuild">
<Copy Condition="'!$(ISx64Server)'" SourceFiles="..\..\..\lib\FluentNHibernate\System.Data.SQLite.dll" DestinationFolder="$(TargetDir)" />
<Copy Condition="'$(ISx64Server)'" SourceFiles="..\..\..\lib\FluentNHibernate\x64\System.Data.SQLite.dll" DestinationFolder="$(TargetDir)" />
</Target>
Nothing too complicated here. If the previously declared property $(ISx64Server) is false, MSBuild will copy the 32 bits assembly in the DestinationFolder. Else, it will copy the 64 bits assembly.
Now, you just have to build the project, let MSBuild to its job, and enjoy an easier life :)