Command line: Packing Windows 8.1 app for deployment

This blog post is a continius work that will get updated when I learn and get new knowledge about how to package Windows 8.1 applications.

While developing Windows 8.1 applications, it is possible and very easy to get MSBuild to packaging up the application when building the application. That is fine for some senarios, but when using continious integration I want to build and packaging the application separtate. For instance when there is a stable tested version of the application there ase no good reasons to build the source every time I need to package that version of application. Then I just want to package the exact binaries that was tested and stable.

Archiving to do this was way more work and try and fail than expected. I have read through a lot of resources online, but the examples I found was for tiny tiny "Hello World" type applications. Therefore when I find my way to get this work I wanted to document the steps I had to go through. In the image below is a rough sketch of what I am setting up. In the Teamcity project for the app I have defined three configurations. One for Development, one for testing and one for production. Each one of them will build and package the app and put the application itself and the builded binaries as artifacts to the build.

winrtpackaging

Building the application

This is the easy part and I a bit out of scope for this blog post, so I will just cover the most important parts from the building process.

I am building all the projects into one output directory and then I am moving some files around to make sure it is in the folder structure that it needs to be for the application to work. Specifically for the application I am going to build I opened the appx package that was built using Visual Studio to get the strukture I needed. I also have a Tools directory in the root of the solution where I have the appxmanifest file that I am going to use. Files like that are files that I am copying into the output directory after the build.

Packing up the application

I am using a powershell script to packaging up the application. Inside that script I am using MakeAppx.exe[1] to create the appx package and Signtool.exe[2] to sign the appx package.

Creating the application package

$makeAppx = Join-Path "C:\Program Files (x86)\Windows Kits\8.1\bin\x86" "makeappx.exe"

if(!(Test-Path $makeAppx)) {
    $localMakeAppx = Join-Path $pwd "Tools\MakeApp\makeappx.exe"
    if(Test-Path $localMakeAppx) {
        $makeAppx = $localMakeAppx
    } else {
        Write-Host "Kunne ikke finne Makeappx.exe på maskinen eller lokalt" -ForegroundColor Magenta
        Exit 1
    }
}

makeappx pack /v /d .\.output /h SHA256 /p YourApplicationName.appx

The first argument /v is just for enabling more output so I can see what is going on in the console. maybe the most important one is the /d argument that specifies the directory that should be packaged. As mentioned I build all the projects into one directory and moveing them into the correct structire. It is also possible to use a mapping file, but I have not used that option. Using it this way is closest to the way I am packageing up desktop applications into an msi installer. The h argument just specify which hash algorithm to use for creating the block map. Valid hash algorithems should be SHA256, SHA384 and SHA512.

Signing the application package

$signTool = "Tools\SignTool\signtool.exe"
$signToolPath = Join-Path $pwd $signTool

if(Test-Path $signToolPath) {
    Set-Alias signtool $signToolPath
} else {
    Write-Host "Kunne ikke finne signtool" -ForegroundColor Magenta
    Exit 1
}
$appxToSign = Join-Path $pwd "CosDocClient.appx"
if(Test-Path $appxToSign) {
    if($certPwd) {
        signtool sign /fd SHA256 /a /f $certPath /p $certPwd .\YourApplicationName.appx
    }
}

The important arguments here are /f that specify the path to the code signing certificate and the /p that specifies the password for the code signing certificate.

To be able to install the application the certificate that is signing the application have to be added as trusted certioficate on the tablet or the computer where the app is going to be installed or the root certificate has to be trusted.

Testing the application

When the application is package into an appx file and signed it is time to test the result. Install the application using one easy powershell command:

PS C:\> Add-AppxPackage .\YOURAPPXPACKAGE.appx

When that is done successfully it is time to start the application and see if everything worked. If the application starts as expected, congratulation it is working fine. If the application get to the splash screen and dies that probably means that something is missing. That is why I figured out it was a good idea to compare the appx content of the application packaged by Visual Studio/MSBuild and the content of the appx package I created myself. The event viewer log do not say that much, it might say something like:

Activation of application 2BEED4F9-1D3F-4C63-868C-DE18BA8247EB_gj89njpjmcwjr!App failed with error: The remote procedure call failed. See the Microsoft-Windows-TWinUI/Operational log for additional information.

That error message that this referncing say a bit more, but not that much.

ActivateApplicationForContractByAppIdAsUserWithHost of the app 2BEED4F9-1D3F-4C63-868C-DE18BA8247EB_gj89njpjmcwjr!App for the Windows.Launch contract failed with The remote procedure call failed..

What I do when I get this message is starting to look for what I missed in the packaging folder. Then I try again and see if that solved it.


  1. App packager (MakeAppx.exe) creates an app package from files on disk or extracts the files from an app package to disk. Starting with Windows 8.1. Read more at MSDN ↩︎

  2. SignTool tool is a command-line tool that digitally signs files, verifies signatures in files, or time stamps files. Read more at MSDN ↩︎

Teis Lindemark

Software developer, beer brewer and AGENT backer

Bergen, Norway https://teilin.net

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.