This project has moved. For the latest updates, please go here.

[Info] Integrate a CPU dependent assembly into an Any CPU Application

Coordinator
Sep 4, 2014 at 6:35 PM
Edited May 14, 2016 at 8:36 PM

This article has been moved to GitHub!


External (3rd party) assemblies comes sometimes with a CPU Platform dependency because they use some native method calls. If the .NET Application uses the Any CPU configuration then the Compiler warns that Any CPU assemblies should not refer CPU dependent assemblies:

Warning: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "D:\Dev\AssemblyMixTest\ClassLibraryX64\bin\Debug\ClassLibraryX64.dll", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.

I prefer to keep the .NET Applications in the Any CPU configuration. This topic shows an approach to load the right assemblies depending on the target CPU architecture.

First, deactivate the compiler warning with a modification of the csproj file. Just add the following PropertyGroup.
<PropertyGroup>
    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None
</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
Then we have to ensure that the CPU dependent assemblies are build or deployed into a subdirectory with the CPU name (e.g. x64 and x86).

We need to use one of the assemblies as reference. It does not matter if we use the x64 or x86 version of this assembly for the reference. But we need to change the “Copy Local” property to “False” in the reference properties. It is important that no Platform dependent assembly lies in the main output folder.

The last step is to create the code that loads these assemblies during startup. The implementation decides which subdirectory should be used by the information provided of the Environment.Is64BitProcess property.
public App()
{
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveHandler;
    ...
}

private Assembly AssemblyResolveHandler(object sender, ResolveEventArgs e)
{
    var platformDirectory = Environment.Is64BitProcess ? @"x64" : @"x86";
    var libPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, 
            platformDirectory);
    var assemblyFile = e.Name.Split(',').First() + ".dll";
    var path = Path.Combine(libPath, assemblyFile);

    return File.Exists(path) ? Assembly.LoadFrom(path) : null;
}