Using Platform Specific Libraries from a Platform Agnostic Project

Scenario: You are writing an application or library which targets the AnyCPU platform, but reference an external library (such as LeadTools) which are platform specific (x86/32 bit, x64/64 bit)

This situation is handled in several places, as there is no one unifying solution which applies to all phases of development.

During the Development Process

Storing the references

Create one folder for each supported platform. These can be placed either in a central location, or a subfolder of the solution/project. Best practice is to name the folder after the target platform. While this is by no means required, it is strongly recommended and urged.

  • x86
  • AMD64
  • IA64 (very rare, not covered in this article, but the same steps apply and will work)

Initial project creation and adding references

Add the references to the project through Visual Studio as you typically would. Choose the binaries which are applicable for the platform which are presently using.

Updating the project file (.csproj)

For this next step, we will edit the project (.csproj) file through a text editor. This can be done directly from the file system, by browsing to the file’s location and editing it in the text editor of your choosing, or through Visual Studio, which has built-in XML editing capabilities, in the following manner:

  1. Right-click on the project from within the Solution Explorer
  2. Select “Unload Project”. The project icon should now be greyed out.
  3. Right-click on the project
  4. Select “Edit ProjectFile.csproj
  5. Edit the file as specified in the steps below
  6. Save changes
  7. Close the file editor window
  8. Right-click on the project from within the Solution Explorer
  9. Select “Reload Project”

Create the property group which handles the platform

Add the following section as a child of the <Project> element, above the first ItemGroup element. The child element, in this case CurrentPlatform will be the name of the property we will late reference. Make sure that the values match the names of the folders created in the “Storing the references” section.

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

Updating reference paths

Update the paths to the references you added originally. Change the platform name in the path to the property name we just created, enclosed with “$()”. In our case, “$(CurrentPlatform)”. You can disregard making changes to the “processorArchitecture” attribute of the references for the fully qualified type name.

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

Verification

To verify that your changes have taken, once the project is reloaded in Visual Studio, check that the path to the reference is now a valid path, with the property for the platform replaced with the correct folder.

The Build Process, Packaging and Distributing Binaries

The Build Process

If your project includes unit tests which are run in a continuous build environment, you must ensure that the correct binaries are found in the working folder of the build server, lest the unit tests all fail when attempting to load the libraries. The simplest method to achieve this goal is to set a post-build event command line script from within Visual Studio. You can do this by going to the “Build Events” tab in the solution properties. For most situations, the following script should suffice. Again, note the property name “CurrentPlatform” is the same that we used when we edited the project file.

xcopy /C /Y "$(SolutionDir)..\Lib\Leadtools\$(CurrentPlatform)\*.*" "$(OutDir)"

Distribution and installation

When distributing the application or library, all applicable binaries must be included with the distribution, and the installation method (automated, .MSI, Setup.exe, deployment personel) must place the correct binaries for the target platform in the folder where the libraries are expected to be found.