Visual Studio: Platform Based References

I’ve been needing to jump back and forth between 32 and 64 bit builds recently. Unfortunately a few of the 3rd party assemblies my project is using are platform specific so I found myself having to manually swap out the references to prevent BadImageFormatExceptions from popping up.  Since Visual Studio doesn’t provide mechanism for this I started exploring external ways to get the right assembly.

On a previous project we where we had this problem we were building with NAnt. With this configuration it was somewhat straightforward to create a dependencies folder that held and organized the different assembly versions and prior to the build, copy the appropriate ones to a folder referenced by the projects. This ensured that we always built the project with the correct assemblies for the target platform.  On this project though, I’m not using NAnt, I’m using MSBuild and I didn’t want to do a custom build task so I looked for another solution.

A 2 year old post from ryangerard.net provided the answer I was looking for.  The solution involves a simple project file “hack” where under each property group we define a variable whose value is the path to the appropriate assembly.

Note: The element name you use should be meaningful to your project. I’ve used ThirdPartyAssemblyPath for illustration purposes.

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
  <!-- snipped -->
  <ThirdPartyAssemblyPath>(path to 32-bit assembly)</ThirdPartyAssemblyPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
  <!-- snipped -->
  <ThirdPartyAssemblyPath>(path to 64-bit assembly)</ThirdPartyAssemblyPath>
</PropertyGroup>

We also need to update the actual reference element to use a hint path based on the variable the variable.

<Reference Include="">
  <HintPath>$(ThirdPartyAssemblyPath)</HintPath>
</Reference>

I was able to leverage a single variable for multiple references because I’m using several assemblies from the same vendor. Since they’re pretty well organized in the vendor’s installation folder I only had to define a single variable for the folder and left the .dll names in the reference definitions.

Once you’ve made these edits you can freely switch between target platforms. I’m not sure how sustainable this is in the long term or on larger projects but it’s definitely an option. Just be careful if you ever need to change that reference that you update the variables rather than the reference or you’ll find yourself right back where you started.

Advertisements