Fishing off the Desktop Bridge. Package Your Appx

Now that you’ve defined how your package will be structured, you need to build the AppX Package. Before getting to that though there are some things you’ll need…

Prerequisites

  • Windows 10 Anniversary update or later. I assume because the anniversary update include the infrastructure to run a Win32 app in a UWP container.
  • Windows 10 SDK. You’ll need this for the tools that will be covered below.
  • A code signing certificate. If you or your organization already have one you’re good to go. If not, create a self signing certificate for yourself.
  • Visual Studio 2015 Update 3. Visual Studio 2017 works too. We’ll use that in a later article for debugging the AppX (Right now it is still a Release Candidate so we’ll stick with 2015)
  • The complete example project is on GitHub.

Setup Visual Studio

We’re going to use build events in VS.NET to build the AppX. This is nice and easy. If you use MSBuild or some other build toolchain the same concepts apply.

Since we are going to use a couple of tools form the Windows SDK, we need to specify its location for the build event scripts. Open your csproj file in a text editor and add this declaration:

   <PropertyGroup>
    <Win10SDKDir Condition=" '$(Win10SDKDir)' == '' ">C:\Program Files (x86)\Windows Kits\10\bin\x64\</Win10SDKDir>
  </PropertyGroup>

Build Event Scripts

The simple package build approach we’ll take looks like this:

  1. After the build, copy all of the files that go into the package to a working folder named (appropriately enough) “AppX”.
  2. Use MakeAppX.exe to package the contents of that folder into a package file.
  3. Sign the package using signtool.exe.
  4. Use Powershell to install our package

Pre-build

Since we’ll rebuild the AppX package each time make sure we cleanup previous outputs at the start of a new build. All paths are relative to the $(TargetDir) location.

:: clean any previous package outputs
rmdir AppX /s /q
del $(TargetName).appx /q /f

Post-build

Let’s walk through the four phases of the build script and then put it all together in a single script at the end.

Collect the Package Contents

:: create the working folder for packaging
mkdir AppX

:: copy output, dependencies, and content into working a folder
xcopy "$(TargetPath)" AppX\ /R /Y
xcopy "$(TargetPath).config" AppX\ /R /Y
xcopy "$(TargetDir)Microsoft.HockeyApp.*.dll" AppX\ /R /Y
xcopy "$(SolutionDir)appxmanifest.xml" AppX\ /R /Y
xcopy "$(SolutionDir)*.png" AppX\ /R /Y

Since our example is pretty simple we’re just dumping everything in the folder root. Be sure to get everything your app needs into the working folder:

  • Build outputs: xcopy "$(TargetPath)"
  • Runtime configuration or data files: xcopy "$(TargetPath).config"
  • Binary dependencies: xcopy "$(TargetDir)Microsoft.HockeyApp.*.dll"
  • The AppXManifest (this needs to be in the root): xcopy "$(SolutionDir)appxmanifest.xml"
  • Content and other assets: xcopy "$(SolutionDir)*.png"

I’ve got the AppXManifest and images in the solution directory so modify those locations as appropriate.

Build and Sign the Package

Next we’re going to use the Windows 10 SDK to make the package and get it ready for installation.
MakeAppX.exe is the sdk tool the generates the package file.

"$(Win10SDKDir)MakeAppX.exe" pack /d AppX /p "$(TargetName).appx"
  • The pack command tells it to create the package
  • /d specifies the working folder to pack
  • /p is the package file name

This will create the package file in the build out directory $(TargetDir). Next we’ll sign the package using SignTool.exe. In this example case I’ve got a signing certificate named tempcastore.pfx, in the solution folder.

"$(Win10SDKDir)SignTool.exe" sign -f "$(SolutionDir)tempcastore.pfx" -fd SHA256 -p YOUR_PFX_PASSWORD -v .\$(TargetName).appx
  • The sign command tell it to the sign the input file
  • -f is the path to the signing certificate
  • -fd SHA256 tells it to use SHA256 for the digest algorithm
  • -p is the password for your pfx file
  • -v is the path to the file to sign

The result is a signed AppX package that we can install and run!

Install the Package

Because the Add-AppXPackage cmdlet won’t install a package with the same version on top of itself doing this in script takes a little finagling. The version Add-AppXPackage is concerned with is in the AppXManifest as an attribute on the Identity element. If you always update that version there’s no need to remove any previous packages. This isn’t convenient when working in the IDE so we’ll remove any previously installed packages in our build script.

powershell if ((Get-AppxPackage -Name '3652dkackman.FishyFishyFish').count -gt 0) { Remove-AppxPackage (Get-AppxPackage -Name '3652dkackman.FishyFishyFish').PackageFullName }
powershell Add-AppxPackage $(TargetName).appx

The first line invokes a powershell command that first checks if the package is installed and removes it if it is. The argument to both Get-AppxPackage and Remove-AppxPackage is the Identity.Name from your AppXManifest.

The second line uses Add-AppxPackage to install the package we just built. If everything worked out right, the package should now be available on your start menu.

Putting it All Together

The complete Post-build script should look like this:

:: create the working folder for packaging
mkdir AppX

:: copy build output, dependencies, and content into the working folder
xcopy "$(TargetPath)" AppX\ /R /Y
xcopy "$(TargetPath).config" AppX\ /R /Y
xcopy "$(TargetDir)Microsoft.HockeyApp.*.dll" AppX\ /R /Y
xcopy "$(SolutionDir)appxmanifest.xml" AppX\ /R /Y
xcopy "$(SolutionDir)*.png" AppX\ /R /Y

:: build and sign the AppX package
"$(Win10SDKDir)MakeAppX.exe" pack /d AppX /p "$(TargetName).appx"
"$(Win10SDKDir)SignTool.exe" sign -f "$(SolutionDir)tempcastore.pfx" -fd SHA256 -p YOUR_PFX_PASSWORD -v .\$(TargetName).appx

:: install it
powershell if ((Get-AppxPackage -Name '3652dkackman.FishyFishyFish').count -gt 0) { Remove-AppxPackage (Get-AppxPackage -Name '3652dkackman.FishyFishyFish').PackageFullName }
powershell Add-AppxPackage $(TargetName).appx

Now every time you change and build your code in the IDE it will be installed as a UWP app. F5 debugging will still start the normal build output not the AppX.

Debugging the AppX from the IDE will be our next step.

Leave a Reply