Gestion de package appx avec les outils en ligne de commande du SDK de développement Windows
Pour les connaisseurs, vous me direz qu’il est possible d’utiliser le designer de package sous Visual Studio qui est très bien documenté dans la documentation MSDN. Et vous avez tout à fait raison. Mais voilà, récemment j’ai été confronté à un bug de Visual Studio 2015 concernant ce fameux designer, bug en cours de correctif. Malheureusement le cycle de développement d’un projet est rarement calé sur le cycle de développement d’un outil. Il faut donc trouver une solution de contournement.
Sans trop rentrer dans les détails de ce bug, je vais quand même vous expliquez comment j’en suis arrivé à devoir générer mon package appx à la main. Il se trouve que le fameux designer de package dont le rôle est de générer un package prêt à être publié sur le Windows Store va modifier à la volée le fichier Package.appxmanifest afin par exemple d’y ajouter des métadonnées. Jusque-là rien de neuf sous le soleil. Le problème est apparu lorsque j’ai souhaité utiliser Cortana et ajouté au fichier manifest l’extension suivante afin de pouvoir lancer mon application depuis Cortana :
<uap:Extension Category="windows.personalAssistantLaunch"/>
A chaque fois que je souhaitais créer un package pour le distribuer à un client via le designer de package :
… l’extension précédente était systématiquement effacer du fichier manifest !!! Plutôt embêtant pour faire valider à mon client une fonctionnalité clef de mon application. Du coup j’ai cherché un moyen de pouvoir générer un package différemment. J’ai pour cela identifié deux scénarios possibles.
Scénario 1 : Modifier le package Appx généré par VS2015
Je suis parti du package appx généré par Visual Studio (package contenant le fichier manifest dont l’extension “windows.personalAssistantLaunch” a été effacé par erreur) et j’ai réalisé les actions suivantes :
- dézipper le package (en effet un fichier appx n’est qu’un fichier d’archive compressé)
- localiser et éditer le fichier manifest dénommé AppxManifest.xml en y ajoutant la fameuse extension manquante
- rezipper le package
- générer un certificat local de signature de code
- signer le package avec le certificat de signature
Pour cela j’ai utilisé les utilitaires disponibles dans le Windows Software Development Kit (SDK) for Windows 10 localisés dans les répertoires suivants :
C:\Program Files (x86)\Windows Kits\10\bin\x86
C:\Program Files (x86)\Windows Kits\10\bin\x64
C:\Program Files (x86)\Windows Kits\10\bin\arm
Dans mon cas je vais générer un fichier appx pour cible desktop (x86). Pensez à modifier votre répertoire si vous souhaitez cibler un jeu d’instructions ARM pour windows phone. Pensez également à ajouter le répertoire “bin” correspondant dans votre variable d’environnement PATH afin de simplifier la saisie de commande. Le répertoire contenant mon fichier appx généré par Visual Studio est le suivant :
Etape 1 : dézipper le fichier MonAppli_1.0.0.0_x86_Debug.appx
- Ouvrez une console en ligne de commande (Touche “Windows” + R puis tapez “cmd” suivi de la touche “Entrée”)
- Déplacez-vous dans le répertoire contenant votre fichier appx généré par Visual Studio
- Dézippez votre fichier appx en tapez la commande suivante :
makeappx.exe unpack /p MonAppli_1.0.0.0_x86_Debug.appx /d .\unpacked /l
Vous obtenez alors un répertoire “unpack” contenant le fameux fichier manifest à éditer :
Etape 2 : rezipper le fichier MonAppli_1.0.0.0_x86_Debug.appx en modifiant son nom
Ouvrez le fichier AppxManifest.xml avec un éditeur de texte et mémorisez la valeur de l’attribut “Publisher” dans la section suivante :
<Identity
Name="f786839b-6b88-4374-8865-cf7628099bbc"
Publisher="CN=myname"
Version="1.0.0.0" />
Ce nom correspond à votre nom d’éditeur de logiciel et nous en aurons besoin ultérieurement pour la génération de certificat numérique.
Un fois le fichier manifest modifié, je vais pouvoir rezipper le fichier appx en tapant la ligne de commande suivante :
makeappx.exe pack /d .\unpacked /p MonAppli_1.0.0.0_x86_Debug_UPDATED.appx /l
Et voici le nouveau fichier appx :
Au passage vous pouvez effacer le répertoire “unpack”.
Etape 3 : générer un certificat de signature de code auto-signé et une clef privée
Et oui … les applications ne peuvent pas s’installer aussi facilement : elles doivent être signées numériquement. Pour cela il est nécessaire de générer un certificat numérique. Si vous regardez bien la capture d’écran précédente, vous y trouverez un fichier certificat d’extension “.cer” qui a été initialement généré par Visual Studio lors de la création du package. Malheureusement nous ne pouvons pas le réutiliser car nous ne connaissons pas le mot de passe de la clef privée associée à ce certificat et utilisée pour la signature. Nous allons donc en créer un nouveau. Donc je vous invite à effacer le fichier MonAppli_1.0.0.0_x86_Debug.cer. Ensuite je vous invite à taper la commande suivante :
makecert.exe -sv MyCertificatePrivate.pvk -n "CN=myname" /h 0 /eku "1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.10.3.13" MyCertificate.cer -a sha256 -r
Cette commande va générer deux fichiers :
- Une clef privée stockée dans un fichier d’extension “.pvk”
- Un certificat numérique de signature stockée dans un fichier d’extension “.cer”
Comme vous l’avez remarqué, l’exécution de cette commande a affiché successivement deux boites de dialogue suivante :
puis
Toute clef privée est en effet protégée par un mot de passe (pensez à le mémoriser car il vous sera redemandé à l’étape suivante).
Etape 4 : convertir le certificat et la clef privée en un unique fichier “pfx”
Afin de signer le fichier appx, nous avons besoin d’un fichier de type “Personal Information Exchange” (format PKCS#12) dont l’extension est “.pfx”. Pour cela nous allons utiliser un autre utilitaire dénommé “pvk2pfx.exe”. Toujours dans la même console, tapez la commande suivante :
pvk2pfx.exe -pvk MyCertificatePrivate.pvk -spc MyCertificate.cer -pfx MyCertificate.pfx
Au passage notez qu’il vous sera demandé de saisir le mot de passe protégeant la clef privée, mot de passe défini lors de l’étape précédente :
Voilà nous avons dorénavant notre fichier pfx et nous sommes prêt à signer notre fichier appx :
Etape 5 : signer le package appx
Pour ce faire, vous allez taper la ligne de commande suivante :
signtool.exe sign /a /v /fd SHA256 /f MyCertificate.pfx MonAppli_1.0.0.0_x86_Debug_UPDATED.appx
Et voilà : dorénavant vous pouvez envoyer votre package appx fraichement générer. Avant d’envoyer le script powershell d’installation, pensez à effacer le fichier appx original.
Ce premier scénario a donc couvert les différentes étapes pour modifier un package appx initialement généré par VS2015. Cela est pratique dans certains cas pour diffuser une version “Debug” en mode “side-loading”. Néanmoins il y a un problème majeur : vous ne pouvez pas publier sur le store un tel package en mode Release. En effet depuis VS2015 le mode Release inclut un mode de compilation .NET Natif afin d’optimiser les performances de votre application. Et malheureusement il n’est pas possible de publier sur le store un package appx précompilé en .NET natif. Vous aurez le message d’erreur suivant :
Nous touchons ici les limites de ce premier scénario. Heureusement il existe une seconde approche : utilisez MSBuild
Scénario 2 : Générer un package appx avec MSBuild
A la différence du premier scénario, nous génèrerons ici le package “from scratch”. Cette génération est réalisée en trois temps :
- Associer votre application avec le store Windows
- Editer votre fichier Package.appxmanifest notamment pour définir le numéro de version (optionnelle)
- Générer votre package en utilisant MsBuild
Etape 1 : Associer votre application avec le store
Depuis Visual Studio, sélectionnez votre projet et cliquez sur le bouton droit de la souris pour afficher le menu contextuel. Puis sélectionnez le menu “Store” puis “Associate App With Store” :
Cette phase nécessite de vous authentifier avec votre compte développeur. Vous pourrez alors sélectionner un nom d’application. Cette association avec le store aura pour conséquence la récupération de deux fichiers qui seront utilisés par la procédure de build pour générer et signer vos différents packages :
- Package.StoreAssociation.xml
- MonAppli_StoreKey.pfx
Etape 2 : Editer votre fichier Package.appxmanifest (Optionnelle)
Cette étape est complètement optionnelle et spécifique à mon besoin d’ajouter une extension pour Cortana. Par ailleurs vous pouvez y définir le numéro de version de votre application (attribut Version de la balise <Identity>). Vous pouvez passer directement à l’étape suivante.
Etape 3 : Générer votre package en utilisant MsBuild
Ouvrez une console en ligne Visual Studio, c’est-à-dire une console paramétrée avec les variables d’environnements nécessaire à l’utilisation de MsBuild. Pour cela, rendez-vous dans le répertoire suivant :
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools
Ensuite ouvrez le batch file VsDevCmd.bat puis lancez la commande suivante :
MSBuild .\MonAppli.csproj /p:Configuration=Release;AppxBundle=Always;AppxBundlePlatforms="x86|x64"
/p:BuildAppxUploadPackageForUap=true
Cette commande aura pour effet :
- de compiler votre projet en mode Release
- de générer un package de type bundle
- de cibler les plateformes x86 et x64 (noter la présence du caractère ‘|’ permettant de lister différentes plateformes cibles dans une même commande)
Au final vous obtiendrez un fichier MonAppli_1.0.0.0_x86_x64_bundle.appxupload que vous pourrez directement charger sur l’interface de publication Dev Center.
Conclusion
En résumé, cet article a exposé deux approches pour générer un package sans utiliser le designer de package intégré à Visual Studio :
- La première méthode pour faire du side-loading de package sans utiliser le designer de Visual Studio
- La seconde méthode pour générer un package de production, bien utile dès qu’on souhaite scripter la procédure de build d’une application Windows store
Références
Packager une application Windows 10 Universelle