Creating a Windows Store App NuGet Package for ARM, x86 and x64

It’s possible to create a NuGet package from a Window Store class library project that contains 3 different DLLs, one for each of the platform types: ARM, x86, and x64.

When the NuGet package is included in a Windows Store app, if the build platform for the app is changed to ARM for example, if the DLL that’s in the NuGet package was built for x86, there will be a build error.

The secret to making this happen is to use the “build” folder in your NuGet package.

This “build” folder sits alongside the lib and content folders.

If we are creating a package to be used in Windows 8.1 Store apps, this build folder will contain a sub folder called “netcore451”. It’s in this folder where the magic happens.

screenshot of file structure

This is a screen shot of the contents of the build folder. (It’s from my open source FeatureToggle library). Notice the platform specific folders. In each of these folder we place the relevant DLL, compiled for each platform.

screenshot of file structure

We also place the x86 version in the lib folder (apparently this can stop Visual Studio/designer from complaining.)

screenshot of file structure

Back to the build folder.

Notice the FeatureToggle.targets file.

For the following to to work it needs to be named the same as the package ID, in the case the NuGet package id is “FeatureToggle”.

The contents of this file allows NuGet to add to the .csproj file in the app that the package is installed into.

The contents of this .targets file look like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="PlatformCheck" BeforeTargets="InjectReference"
    Condition=" ( ('$(Platform)' != 'x86') AND ('$(Platform)' != 'ARM') AND  ('$(Platform)' != 'x64') )">
    <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' 
                     platform. You need to specify platform (x86 / x64 or ARM)." />
  </Target>
  
  <Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">

    <ItemGroup Condition=" '$(Platform)' == 'x86' or '$(Platform)' == 'x64' or '$(Platform)' == 'ARM'">
      <Reference Include="FeatureToggle.WindowsStore">
        <HintPath>$(MSBuildThisFileDirectory)$(Platform)\FeatureToggle.WindowsStore.dll</HintPath>
      </Reference>
    </ItemGroup>

  </Target>
</Project>

When the NuGet package is installed it will change the host apps .csproj file and add in the logic contained in this targets file. Now, before the app is built, the current build platform will be examined and the reference will be changed so that the relevant platform binary is used from either the ARM, x86, or x64 folder in our NuGet build folder. If the platform is not set to either ARM, x86, or x64 then the build will error with a message saying that a specific platform needs to be built –as opposed to AnyCPU for example.

The .targets file above is based on this MSDN article by Sebastien Pertus. The article also discusses packaging WinRT components.

SHARE: