Creación de paquetes con el diseño del empaquetado

Con la introducción de los paquetes de recursos, los desarrolladores ahora tienen las herramientas para compilar más paquetes además de más tipos de paquetes. A medida que una aplicación se hace más grande y compleja, a menudo se compone de más paquetes, y la dificultad de administrar estos paquetes aumentará (especialmente si está creando fuera de Visual Studio y usando archivos de asignación). Para simplificar la administración de la estructura de empaquetado de una aplicación, puede usar el diseño de empaquetado admitido por MakeAppx.exe.

El diseño de empaquetado es un único documento XML que describe la estructura de empaquetado de la aplicación. Especifica los paquetes de una aplicación (principal y opcional), los paquetes de los paquetes y los archivos de los paquetes. Los archivos se pueden seleccionar entre carpetas, unidades y ubicaciones de red diferentes. Los caracteres comodín se pueden usar para seleccionar o excluir archivos.

Una vez configurado el diseño de empaquetado de una aplicación, se usa con MakeAppx.exe para crear todos los paquetes de una aplicación en una sola llamada de línea de comandos. El diseño del empaquetado se puede editar para modificar la estructura del paquete para que se adapte a sus necesidades de implementación.

Ejemplo de diseño de empaquetado simple

Este es un ejemplo del aspecto de un diseño de empaquetado 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>

Vamos a dividir este ejemplo para comprender cómo funciona.

PackageFamily

Este diseño de empaquetado creará un único archivo de agrupación de aplicaciones planas con un paquete de arquitectura x64 y un paquete de recursos "Multimedia".

El elemento PackageFamily se usa para definir una agrupación de aplicaciones. Debe usar el atributo ManifestPath para proporcionar un AppxManifest para la agrupación; AppxManifest debe corresponder a AppxManifest para el paquete de arquitectura de la agrupación. También se debe proporcionar el atributo ID. Esto se usa con MakeAppx.exe durante la creación del paquete para que pueda crear solo este paquete si lo desea, y este será el nombre de archivo del paquete resultante. El atributo FlatBundle se usa para describir qué tipo de agrupación desea crear, true para un conjunto plano (sobre el que puede obtener más información) y false para un conjunto clásico. El atributo ResourceManager se usa para especificar si los paquetes de recursos de esta agrupación usarán MRT para acceder a los archivos. Esto es true de forma predeterminada,pero a partir de Windows 10, versión 1803, esto aún no está listo, por lo que este atributo debe establecerse en false.

Paquete y AssetPackage

Dentro de PackageFamily, se definen los paquetes que contiene la agrupación de aplicaciones o referencias. Aquí, el paquete de arquitectura (también denominado paquete principal) se define con el elemento Package y el paquete de recursos se define con el elemento AssetPackage. El paquete de arquitectura debe especificar para qué arquitectura es el paquete, ya sea "x64", "x86", "arm" o "neutral". También puede (opcionalmente) proporcionar directamente un AppxManifest específicamente para este paquete mediante el atributo ManifestPath de nuevo. Si no se proporciona AppxManifest, se generará automáticamente uno a partir del appxManifest proporcionado para PackageFamily.

De forma predeterminada, se generarán y AppxManifest para cada paquete dentro de la agrupación. Para el paquete de recursos, también puede establecer el atributo AllowExecution. Si se establece en false (valor predeterminado), ayudará a reducir el tiempo de publicación de la aplicación, ya que los paquetes que no necesitan ejecutarse no bloquearán el proceso de publicación (puede obtener más información al respecto en Introducción a los paquetes de recursos).

Archivos

Dentro de cada definición de paquete, puede usar el elemento File para seleccionar los archivos que se incluirán en este paquete. El atributo SourcePath es donde se encuentran los archivos localmente. Puede seleccionar archivos de carpetas diferentes (proporcionando rutas de acceso relativas), unidades diferentes (proporcionando rutas de acceso absolutas) o incluso recursos compartidos de red (proporcionando algo como \\myshare\myapp\* ). DestinationPath es donde los archivos terminarán dentro del paquete, en relación con la raíz del paquete. ExcludePath se puede usar (en lugar de los otros dos atributos) para seleccionar los archivos que se excluirán de los seleccionados por los atributos SourcePath de otros elementos File dentro del mismo paquete.

Cada elemento File se puede usar para seleccionar varios archivos mediante caracteres comodín. En general, un solo carácter comodín ( * ) se puede usar en cualquier lugar dentro de la ruta de acceso un número cualquiera de veces. Sin embargo, un único carácter comodín solo coincidirá con los archivos de una carpeta y no con ninguna subcarpeta. Por ejemplo, C:\MyGame\*\* se puede usar en C:\MyGame\*\* para seleccionar los archivos C:\MyGame\Audios\UI.mp3 y , pero no puede seleccionar C:\MyGame\Videos\intro.mp4C:\MyGame\Audios\Level1\warp.mp3 . El carácter comodín doble ( ) también se puede usar en lugar de nombres de carpeta o archivo para que coincidan con cualquier cosa de forma recursiva (pero no puede estar junto a ** nombres parciales). Por ejemplo, C:\MyGame\**\Level1\** puede seleccionar C:\MyGame\Audios\Level1\warp.mp3 y C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4 . Los caracteres comodín también se pueden usar para cambiar directamente los nombres de archivo como parte del proceso de empaquetado si los caracteres comodín se usan en distintos lugares entre el origen y el destino. Por ejemplo, tener C:\MyGame\Audios\* para C:\MyGame\Audios\*Sound\copy_* para Sound\copy_* puede seleccionar C:\MyGame\Audios\UI.mp3 y hacer que aparezca en el paquete como Sound\copy_UI.mp3 . En general, el número de caracteres comodín únicos y caracteres comodín dobles debe ser el mismo para SourcePath y DestinationPath de un único elemento File.

Ejemplo de diseño de empaquetado avanzado

Este es un ejemplo de un diseño de empaquetado más complicado:

<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>

Este ejemplo difiere del ejemplo simple con la adición de elementos ResourcePackagey Optional.

Los paquetes de recursos se pueden especificar con el elemento ResourcePackage. Dentro de ResourcePackage, el elemento Resources debe usarse para especificar los calificadores de recursos del paquete de recursos. Los calificadores de recursos son los recursos admitidos por el paquete de recursos. Aquí podemos ver que hay dos paquetes de recursos definidos y cada uno contiene los archivos específicos de inglés y francés. Un paquete de recursos puede tener más de un calificador; para ello, agregue otro elemento Resource en Resources. También se debe especificar un recurso predeterminado para la dimensión de recursos si la dimensión existe (dimensiones que son lenguaje, escala, tamaño). En este caso, podemos ver que el inglés es el idioma predeterminado, lo que significa que para los usuarios que no tienen un idioma del sistema de francés establecido, se reservarán la descarga del paquete de recursos en inglés y se mostrarán en inglés.

Los paquetes opcionales tienen sus propios nombres de familia de paquetes distintos y deben definirse con elementos PackageFamily, al tiempo que se especifica que el atributo Optional sea true. El atributo RelatedSet se usa para especificar si el paquete opcional está dentro del conjunto relacionado (de forma predeterminada es true): si el paquete opcional debe actualizarse con el paquete principal.

El elemento PrebuiltPackage se usa para agregar paquetes que no están definidos en el diseño de empaquetado que se van a incluir o hacer referencia en los archivos de agrupación de aplicaciones que se van a compilar. En este caso, se incluye otro paquete opcional de DLC aquí para que el archivo de agrupación de aplicaciones principal pueda hacer referencia a él y hacer que sea parte del conjunto relacionado.

Compilación de paquetes de aplicación con un diseño de empaquetado y MakeAppx.exe

Una vez que tenga el diseño de empaquetado de la aplicación, puede empezar a usar MakeAppx.exe para compilar los paquetes de la aplicación. Para compilar todos los paquetes definidos en el diseño de empaquetado, use el comando :

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

Sin embargo, si va a actualizar la aplicación y algunos paquetes no contienen archivos modificados, puede compilar solo los paquetes que han cambiado. Con el ejemplo de diseño de empaquetado simple en esta página y la creación del paquete de arquitectura x64, este es el aspecto que tendría nuestro comando:

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

La marca se puede usar para seleccionar los paquetes que se crearán a partir del diseño de empaquetado, correspondiente al /id atributo /id del diseño. se /ip usa para indicar dónde se encuentra la versión anterior de los paquetes en este caso. Se debe proporcionar la versión anterior porque el archivo de agrupación de aplicaciones todavía debe hacer referencia a la versión anterior del paquete multimedia. La marca se usa para incrementar automáticamente la versión de los paquetes que se están generando (en lugar de cambiar la versión /iv en /iv). Como alternativa, los modificadores y se pueden usar para proporcionar directamente una versión del paquete (para todos los paquetes que se crearán) y una versión de agrupación (para que se puedan crear todas las /pv/bv agrupaciones), respectivamente. Con el ejemplo de diseño de empaquetado avanzado de esta página, si solo desea compilar el paquete opcional Themes y el paquete de aplicación Themes.main al que hace referencia, usaría este comando:

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

La marca se usa para indicar que también se deben crear los secundarios del conjunto de temas (en este caso se va a crear /bcThemes.main)./bc La marca se usa para indicar que no se debe crear el elemento primario de la agrupación /nbp de temas. /nbp El elemento primario de Themes, que es un paquete de aplicaciones opcional, es el paquete de aplicaciones principal: MyGame. Normalmente, para un paquete opcional en un conjunto relacionado, también se debe crear el paquete de aplicación principal para que el paquete opcional se pueda instalar, ya que también se hace referencia al paquete opcional en el paquete de aplicación principal cuando se encuentra en un conjunto relacionado (para garantizar el control de versiones entre los paquetes principal y opcional). La relación de elementos secundarios primarios entre paquetes se ilustra en el diagrama siguiente:

Diagrama de diseño de empaquetado