Conditionally use 32/64 bit reference when building in Visual Studio

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.

<!-- Properties group for Determining 64bit Architecture -->
<PropertyGroup>
  <CurrentPlatform>x86</CurrentPlatform>
  <CurrentPlatform Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">AMD64</CurrentPlatform>
</PropertyGroup>

Then, for your platform specific references, you make changes such as the following:

<ItemGroup>
  <Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath>
  </Reference>
  <Reference Include="System" />
  <Reference Include="System.Core" />
  <Reference Include="System.Data.Entity" />
  <!--  Other project references -->
</ItemGroup>

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:

  • Replace the $(PROCESSOR_ARCHITEW6432) and $(PROCESSOR_ARCHITECTURE) with $(Platform) to consider ONLY the target platform of the projects
  • Alter the platform determination logic in order to be appropriate to the current machine, so that you're not building/referencing a 64 bit binary to execute on a 32 bit platform.

I 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.


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"

<!-- this group contains references that are not platform specific -->
<ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <!-- any other references that aren't platform specific -->
</ItemGroup>

<!-- x86 specific references -->
<ItemGroup Condition=" '$(Platform)' == 'x86' ">
    <Reference Include="MyComAssembly.Interop">
        <HintPath>..\..\lib\x86\MyComAssembly.Interop.dll</HintPath>
    </Reference>

    <!-- any additional x86 specific references -->
</ItemGroup>

<!-- x64 specific referneces -->
<ItemGroup Condition=" '$(Platform)' == 'x64' ">
    <Reference Include="MyComAssembly.Interop">
        <HintPath>..\..\lib\x64\MyComAssembly.Interop.dll</HintPath>
    </Reference>

    <!-- any additional x64 specific references -->
</ItemGroup>

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