Création de package à l’aide de la disposition de mise en package

Avec l’introduction des packages de ressources, les développeurs disposent désormais d’outils permettant de créer plus de packages en plus de types de package. à mesure qu’une application devient plus volumineuse et plus complexe, elle est souvent composée d’un plus grand nombre de packages, et la difficulté de la gestion de ces packages augmente (surtout si vous créez en dehors de Visual Studio et en utilisant des fichiers de mappage). Pour simplifier la gestion de la structure de packaging d’une application, vous pouvez utiliser la disposition d’empaquetage prise en charge par MakeAppx.exe.

La disposition d’empaquetage est un document XML unique qui décrit la structure de Packaging de l’application. Il spécifie les offres groupées d’une application (principale et facultative), les packages dans le regroupement et les fichiers des packages. Les fichiers peuvent être sélectionnés à partir de dossiers, de lecteurs et d’emplacements réseau différents. Les caractères génériques peuvent être utilisés pour sélectionner ou exclure des fichiers.

Une fois la disposition d’empaquetage d’une application configurée, elle est utilisée avec MakeAppx.exe pour créer tous les packages d’une application dans un appel de ligne de commande unique. La disposition de l’empaquetage peut être modifiée pour modifier la structure du package en fonction de vos besoins en matière de déploiement.

Exemple de disposition d’empaquetage simple

Voici un exemple de ce à quoi ressemble une disposition d’empaquetage simple :

<PackagingLayout xmlns="http://schemas.microsoft.com/appx/makeappx/2017">
  <PackageFamily ID="MyGame" FlatBundle="true" ManifestPath="C:\mygame\appxmanifest.xml" ResourceManager="false">
    
    <!-- x64 code package-->
    <Package ID="x64" ProcessorArchitecture="x64">
      <Files>
        <File DestinationPath="*" SourcePath="C:\mygame\*"/>
        <File ExcludePath="*C:\mygame\*.txt"/>
      </Files>
    </Package>
    
    <!-- Media asset package -->
    <AssetPackage ID="Media" AllowExecution="false">
      <Files>
        <File DestinationPath="Media\**" SourcePath="C:\mygame\media\**"/>
      </Files>
    </AssetPackage>

  </PackageFamily>
</PackagingLayout>

Nous allons arrêter cet exemple pour comprendre comment il fonctionne.

PackageFamily

Cette disposition de Packaging crée un fichier de bundle d’applications plat unique avec un package d’architecture x64 et un package de ressources « média ».

L’élément PackageFamily est utilisé pour définir un bundle d’applications. Vous devez utiliser l’attribut ManifestPath pour fournir un AppxManifest pour le bundle, AppxManifest doit correspondre au AppxManifest pour le package d’architecture du bundle. L’attribut ID doit également être fourni. Elle est utilisée avec MakeAppx.exe lors de la création du package, ce qui vous permet de créer ce package uniquement si vous le souhaitez, et il s’agit du nom de fichier du package résultant. L’attribut FlatBundle est utilisé pour décrire le type de Bundle que vous souhaitez créer, true pour un bundle plat (vous pouvez en savoir plus ici) et false pour un bundle classique. L’attribut ResourceManager est utilisé pour spécifier si les packages de ressources de ce bundle utilisent le MRT pour accéder aux fichiers. par défaut, cette valeur est true, mais à partir de Windows 10, la version 1803, qui n’est pas encore prête, cet attribut doit être défini sur false.

Package et AssetPackage

Dans le PackageFamily, les packages que le bundle d’application contient ou référence sont définis. Ici, le package d’architecture (également appelé « package principal ») est défini avec l’élément de package , et le package de ressources est défini avec l’élément AssetPackage . Le package d’architecture doit spécifier l’architecture pour laquelle le package est destiné, soit « x64 », « x86 », « ARM » ou « neutre ». Vous pouvez également (si vous le souhaitez) fournir directement un AppxManifest spécifiquement pour ce package à l’aide de l’attribut ManifestPath . Si un AppxManifest n’est pas fourni, l’un d’eux est généré automatiquement à partir du AppxManifest fourni pour le PackageFamily.

Par défaut, et AppxManifest sont générés pour chaque package au sein du regroupement. Pour le package de ressources, vous pouvez également définir l’attribut AllowExecution . Si vous définissez cette valeur sur false (valeur par défaut), vous pourrez réduire le temps de publication de votre application, car les packages qui n’ont pas besoin d’être exécutés n’auront pas d’analyse antivirus bloquer le processus de publication (vous pouvez en savoir plus à ce sujet à la Présentation des packages d’actifs).

Fichiers

Dans chaque définition de package, vous pouvez utiliser l’élément file pour sélectionner les fichiers à inclure dans ce package. L’attribut SourcePath est l’emplacement local des fichiers. Vous pouvez sélectionner des fichiers dans différents dossiers (en fournissant des chemins d’accès relatifs), des lecteurs différents (en fournissant des chemins d’accès absolus) ou même des partages réseau (en fournissant des éléments comme \\myshare\myapp\* ). Le DestinationPath est l’emplacement où les fichiers finissent au sein du package, par rapport à la racine du package. ExcludePath peut être utilisé (au lieu des deux autres attributs) pour sélectionner les fichiers à exclure de ceux sélectionnés par d’autres attributs SourcePath d’éléments de fichier dans le même package.

Chaque élément de fichier peut être utilisé pour sélectionner plusieurs fichiers en utilisant des caractères génériques. En général, un caractère générique unique ( * ) peut être utilisé n’importe où dans le chemin d’accès un nombre quelconque de fois. Toutefois, un caractère générique unique correspond uniquement aux fichiers contenus dans un dossier, et non à des sous-dossiers. Par exemple, C:\MyGame\*\* peut être utilisé dans le SourcePath pour sélectionner les fichiers C:\MyGame\Audios\UI.mp3 et C:\MyGame\Videos\intro.mp4 , mais il ne peut pas sélectionner C:\MyGame\Audios\Level1\warp.mp3 . Le double caractère générique ( ** ) peut également être utilisé à la place de noms de dossiers ou de fichiers pour correspondre à tout ce qui est de manière récursive (mais il ne peut pas être en regard de noms partiels). Par exemple, C:\MyGame\**\Level1\** peut sélectionner C:\MyGame\Audios\Level1\warp.mp3 et C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4 . Les caractères génériques peuvent également être utilisés pour modifier directement les noms de fichiers dans le cadre du processus d’empaquetage si les caractères génériques sont utilisés dans différents emplacements entre la source et la destination. Par exemple, C:\MyGame\Audios\* le fait d’avoir pour SourcePath et Sound\copy_* pour DestinationPath peut sélectionner C:\MyGame\Audios\UI.mp3 et le faire apparaître dans le package sous la forme Sound\copy_UI.mp3 . En général, le nombre de caractères génériques uniques et de caractères génériques doubles doit être identique pour SourcePath et DestinationPath d’un seul élément de fichier .

Exemple de disposition de Packaging avancé

Voici un exemple de disposition de Packaging plus complexe :

<PackagingLayout xmlns="http://schemas.microsoft.com/appx/makeappx/2017">
  <!-- Main game -->
  <PackageFamily ID="MyGame" FlatBundle="true" ManifestPath="C:\mygame\appxmanifest.xml" ResourceManager="false">
    
    <!-- x64 code package-->
    <Package ID="x64" ProcessorArchitecture="x64">
      <Files>
        <File DestinationPath="*" SourcePath="C:\mygame\*"/>
        <File ExcludePath="*C:\mygame\*.txt"/>
      </Files>
    </Package>

    <!-- Media asset package -->
    <AssetPackage ID="Media" AllowExecution="false">
      <Files>
        <File DestinationPath="Media\**" SourcePath="C:\mygame\media\**"/>
      </Files>
    </AssetPackage>
    
    <!-- English resource package -->
    <ResourcePackage ID="en">
      <Files>
        <File DestinationPath="english\**" SourcePath="C:\mygame\english\**"/>
      </Files>
      <Resources Default="true">
        <Resource Language="en"/>
      </Resources>
    </ResourcePackage>

    <!-- French resource package -->
    <ResourcePackage ID="fr">
      <Files>
        <File DestinationPath="french\**" SourcePath="C:\mygame\french\**"/>
      </Files>
      <Resources>
        <Resource Language="fr"/>
      </Resources>
    </ResourcePackage>
  </PackageFamily>

  <!-- DLC in the related set -->
  <PackageFamily ID="DLC" Optional="true" ManifestPath="C:\DLC\appxmanifest.xml">
    <Package ID="DLC.x86" Architecture="x86">
      <Files>
        <File DestinationPath="**" SourcePath="C:\DLC\**"/>
      </Files>
    </Package>
  </PackageFamily>

  <!-- DLC not part of the related set -->
  <PackageFamily ID="Themes" Optional="true" RelatedSet="false" ManifestPath="C:\themes\appxmanifest.xml">
    <Package ID="Themes.main" Architecture="neutral">
      <Files>
        <File DestinationPath="**" SourcePath="C:\themes\**"/>
      </Files>
    </Package>
  </PackageFamily>

  <!-- Existing packages that need to be included/referenced in the bundle -->
  <PrebuiltPackage Path="C:\prebuilt\DLC2.appxbundle" />

</PackagingLayout>

Cet exemple diffère de l’exemple simple avec l’ajout de ResourcePackage et d’éléments facultatifs .

Les packages de ressources peuvent être spécifiés avec l’élément ResourcePackage . Dans ResourcePackage, l’élément Resources doit être utilisé pour spécifier les qualificateurs de ressources du Pack de ressources. Les qualificateurs de ressources sont les ressources qui sont prises en charge par le Pack de ressources, ici, nous pouvons voir que deux packs de ressources sont définis et qu’ils contiennent chacun les fichiers spécifiques en anglais et en français. Un pack de ressources peut avoir plusieurs qualificateurs. pour ce faire, vous pouvez ajouter un autre élément de ressource dans les ressources. Une ressource par défaut pour la dimension de ressource doit également être spécifiée si la dimension existe (les dimensions sont Language, Scale, dxfl). Ici, nous pouvons voir que l’anglais est la langue par défaut, ce qui signifie que pour les utilisateurs qui ne disposent pas d’une langue système définie par le français, ils sont en mesure de télécharger le Pack de ressources en anglais et d’afficher en anglais.

Les packages facultatifs ont chacun leurs propres noms de famille de packages et doivent être définis avec des éléments PackageFamily , tout en spécifiant l’attribut facultatif pour avoir la valeur true. L’attribut RelatedSet est utilisé pour spécifier si le package facultatif se trouve dans l’ensemble associé (par défaut, cette valeur est true), si le package facultatif doit être mis à jour avec le package principal.

L’élément PrebuiltPackage est utilisé pour ajouter des packages qui ne sont pas définis dans la disposition d’empaquetage à inclure ou à référencer dans le ou les fichiers de l’ensemble d’applications à générer. Dans ce cas, un autre package DLC facultatif est inclus ici afin que le fichier de bundle d’applications principal puisse le référencer et faire partie de l’ensemble associé.

Créer des packages d’application avec une disposition de Packaging et des MakeAppx.exe

Une fois que vous disposez de la disposition d’empaquetage de votre application, vous pouvez commencer à utiliser MakeAppx.exe pour générer les packages de votre application. Pour générer tous les packages définis dans la disposition de Packaging, utilisez la commande :

MakeAppx.exe build /f PackagingLayout.xml /op OutputPackages\

Toutefois, si vous mettez à jour votre application et que certains packages ne contiennent aucun fichier modifié, vous pouvez générer uniquement les packages qui ont été modifiés. À l’aide de l’exemple de disposition d’empaquetage simple sur cette page et de la génération du package d’architecture x64, il s’agit de la commande qui ressemble à ce qui suit :

MakeAppx.exe build /f PackagingLayout.xml /id "x64" /ip PreviousVersion\ /op OutputPackages\ /iv

L' /id indicateur peut être utilisé pour sélectionner les packages à générer à partir de la disposition d’empaquetage, correspondant à l’attribut ID dans la disposition. /ipEst utilisé pour indiquer où se trouve la version précédente des packages dans ce cas. La version précédente doit être fournie, car le fichier de bundle d’applications doit toujours faire référence à la version précédente du package multimédia . L' /iv indicateur est utilisé pour incrémenter automatiquement la version des packages en cours de génération (au lieu de modifier la version dans le AppxManifest). Les commutateurs /pv et peuvent également /bv être utilisés pour fournir directement une version de package (pour tous les packages à créer) et une version d’offre groupée (pour toutes les offres groupées à créer), respectivement. À l’aide de l’exemple de disposition de Packaging avancé sur cette page, si vous souhaitez uniquement générer le bundle facultatif Themes et le package de l’application Themes. main qu’il référence, vous devez utiliser cette commande :

MakeAppx.exe build /f PackagingLayout.xml /id "Themes" /op OutputPackages\ /bc /nbp

L' /bc indicateur est utilisé pour indiquer que les enfants du bundle de thèmes doivent également être générés (dans ce cas, Themes. main sera généré). L' /nbp indicateur est utilisé pour indiquer que le parent de l’ensemble de thèmes ne doit pas être généré. Le parent de Themes, qui est un bundle d’applications facultatif, est l’offre groupée d’applications principales : MyGame. En règle générale, pour un package facultatif dans un ensemble associé, le bundle d’applications principal doit également être généré pour que le package facultatif soit utilisable, puisque le package facultatif est également référencé dans le bundle d’applications principal lorsqu’il se trouve dans un ensemble associé (pour garantir le contrôle de version entre le package principal et les packages facultatifs). La relation parent-enfant entre les packages est illustrée dans le diagramme suivant :

Diagramme de disposition d’empaquetage