Creación de paquetes con el diseño del empaquetadoPackage creation with the packaging layout

Con la introducción de paquetes de activos, los desarrolladores ahora tienen las herramientas para crear más paquetes además de más tipos.With the introduction of asset packages, developers now have the tools to build more packages in addition to more package types. Cuanto más grande y compleja es una aplicación, generalmente consta de más paquetes y aumenta la dificultad de administrarlos (especialmente si se crean fuera de Visual Studio y usando archivos de asignación).As an app gets larger and more complex, it will often be comprised of more packages, and the difficulty of managing these packages will increase (especially if you are building outside of Visual Studio and using mapping files). Para simplificar la administración de la estructura de empaquetado de una aplicación, puedes usar el diseño de empaquetado admitido por MakeAppx.exe.To simplify the management of an app’s packaging structure, you can use the packaging layout supported by MakeAppx.exe.

El diseño del empaquetado es un solo documento XML que describe la estructura del empaquetado de la aplicación.The packaging layout is a single XML document that describes packaging structure of the app. Especifica los lotes de una aplicación (principal y opcional), los paquetes de los lotes y los archivos de los paquetes.It specifies the bundles of an app (primary and optional), the packages in the bundles, and the files in the packages. Los archivos se pueden seleccionar desde carpetas, unidades y ubicaciones de red diferentes.Files can be selected from different folders, drives, and network locations. Pueden usarse caracteres comodín para seleccionar o excluir archivos.Wildcards can be used to select or exclude files.

Después de configurar 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.After the packaging layout for an app has been set up, it's used with MakeAppx.exe to create all of the packages for an app in a single command line call. El diseño de empaquetado puede modificarse para alterar la estructura del paquete para satisfacer tus necesidades de implementación.The packaging layout can be edited to alter the package structure to fit your deployment needs.

Ejemplo de diseño de empaquetado simpleSimple packaging layout example

Este es un ejemplo del aspecto de un diseño de empaquetado simple:Here's an example of what a simple packaging layout looks like:

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

Desglosemos este ejemplo para comprender cómo funciona.Let's break this example down to understand how it works.

PackageFamilyPackageFamily

Este diseño de empaquetado creará un único archivo de paquete de aplicación sin formato con un paquete de arquitectura x64 y un paquete de activos de "medios".This packaging layout will create a single flat app bundle file with an x64 architecture package and a “Media” asset package.

El elemento PackageFamily se usa para definir una recopilación de aplicaciones.The PackageFamily element is used to define an app bundle. Debes usar el atributo ManifestPath para proporcionar un AppxManifest para la recopilación, el AppxManifest debe coincidir con elAppxManifest para el paquete de arquitectura de la recopilación.You must use the ManifestPath attribute to provide an AppxManifest for the bundle, the AppxManifest should correspond to the AppxManifest for the architecture package of the bundle. El atributo ID también debe proporcionarse.The ID attribute must also be provided. Esto se usa con MakeAppx.exe durante la creación del paquete para que puedas crear solo este paquete si quieres, y este será el nombre de archivo del paquete resultante.This is used with MakeAppx.exe during package creation so that you can create just this package if you want to, and this will be the file name of the resulting package. El atributo FlatBundle se usa para describir qué tipo de recopilación quieres crear, true para una recopilación plana (aquí puedes leer más sobre ella), y false para una recopilación clásica.The FlatBundle attribute is used to describe what type of bundle you want to create, true for a flat bundle (which you can read more about here), and false for a classic bundle. El atributo ResourceManager se usa para especificar si los paquetes de recursos dentro de esta recopilación usarán MRT para acceder a los archivos.The ResourceManager attribute is used to specify if the resource packages within this bundle will use MRT in order to access the files. De manera predeterminada es true, pero a partir de Windows 10, versión 1803, este aún no está listo, por lo que este atributo debe establecerse en false.This is by default true, but as of Windows 10, version 1803, this is not yet ready, so this attribute must be set to false.

Package y AssetPackagePackage and AssetPackage

Dentro de PackageFamily, se definen los paquetes que contiene o a los que hace referencia.Within the PackageFamily, the packages that the app bundle contains or references are defined. Aquí, el paquete de la arquitectura (también llamado paquete principal) se define con el elemento Package y el paquete de activos se define con el elemento AssetPackage.Here, the architecture package (also called the main package) is defined with the Package element, and the asset package is defined with the AssetPackage element. El paquete de arquitectura debe especificar para qué arquitectura es el paquete, "x64", "x86", "arm" o "neutral".The architecture package must specify which architecture the package is for, either “x64”, “x86”, “arm”, or “neutral”. También puedes (opcionalmente) proporcionar directamente un AppxManifest específicamente para este paquete usando de nuevo el atributo ManifestPath.You can also (optionally) directly provide an AppxManifest specifically for this package by using the ManifestPath attribute again. Si una AppxManifest no siempre se generará automáticamente desde la AppxManifest proporcionado para la PackageFamily .If an AppxManifest is not provided, one will be automatically generated from the AppxManifest provided for the PackageFamily.

De manera predeterminada y AppxManifest se generará para cada paquete dentro de la recopilación.By default and AppxManifest will be generated for every package within the bundle. Para el paquete de activos, también puedes establecer el atributo AllowExecution.For the asset package, you can also set the AllowExecution attribute. Si se establece en false (predeterminado), te ayudará a reducir el tiempo de publicación de tu aplicación ya que los paquetes que no tienen que ejecutarse no tendrán su detección de virus bloqueando el proceso de publicación (puedes aprender más sobre esto en Introducción a paquetes de activos).Setting this to false (the default), will help decrease the publishing time for your app since packages that don’t need to execute won’t have their virus scan block the publishing process (you can learn more about this at Introduction to asset packages).

ArchivosFiles

Dentro de la definición de cada paquete, puedes usar el elemento File para seleccionar archivos que se van a incluir en este paquete.Within each package definition, you can use the File element to select files to be included in this package. El atributo SourcePath es donde están los archivos localmente.The SourcePath attribute is where the files are locally. Puedes seleccionar archivos desde 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\*).You can select files from different folders (by providing relative paths), different drives (by providing absolute paths), or even network shares (by providing something like \\myshare\myapp\*). La DestinationPath es donde los archivos acabarán dentro del paquete, en relación con la raíz del paquete.The DestinationPath is where the files will end up within the package, relative to the package root. ExcludePath puede utilizarse (en lugar de los otros dos atributos) para seleccionar archivos que se van a excluir de los seleccionados con otros atributos SourcePath de los elementos File dentro del mismo paquete.ExcludePath can be used (instead of the other two attributes) to select files to be excluded from the ones selected by other File elements’ SourcePath attributes within the same package.

Cada elemento File puede usarse para seleccionar varios archivos utilizando caracteres comodín.Each File element can be used to select multiple files by using wildcards. En general, un solo comodín (*) se puede usar en cualquier parte dentro de la ruta de acceso cualquier número de veces.In general, single wildcard (*) can be used anywhere within the path any number of times. Sin embargo, un solo carácter comodín solo coincidirá con los archivos dentro de una carpeta y no en las subcarpetas.However, a single wildcard will only match the files within a folder and not any subfolders. Por ejemplo, C:\MyGame\*\* puede usarse en SourcePath para seleccionar los archivos C:\MyGame\Audios\UI.mp3 y C:\MyGame\Videos\intro.mp4, pero no puede seleccionar C:\MyGame\Audios\Level1\warp.mp3.For example, C:\MyGame\*\* can be used in the SourcePath to select the files C:\MyGame\Audios\UI.mp3 and C:\MyGame\Videos\intro.mp4, but it cannot select C:\MyGame\Audios\Level1\warp.mp3. El comodín doble (**) también puede usarse en lugar de nombres de carpeta o archivo para que coincidan con cualquier cosa de forma recursiva (pero no puede ser junto a nombres parciales).The double wildcard (**) can also be used in place of folder or file names to match anything recursively (but it cannot be next to partial names). Por ejemplo, C:\MyGame\**\Level1\** puede seleccionar C:\MyGame\Audios\Level1\warp.mp3 y C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4.For example, C:\MyGame\**\Level1\** can select C:\MyGame\Audios\Level1\warp.mp3 and C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4. También pueden usarse caracteres comodín para cambiar directamente los nombres de archivo como parte del proceso de empaquetado si se usan los caracteres comodín en lugares diferentes entre el origen y el destino.Wildcards can also be used to directly change file names as part of the packaging process if the wildcards are used in different places between the source and destination. Por ejemplo, tener C:\MyGame\Audios\* para SourcePath y Sound\copy_* para DestinationPath puede seleccionar C:\MyGame\Audios\UI.mp3 y hacer que aparezca en el paquete como Sound\copy_UI.mp3.For example, having C:\MyGame\Audios\* for SourcePath and Sound\copy_* for DestinationPath can select C:\MyGame\Audios\UI.mp3 and have it appear in the package as Sound\copy_UI.mp3. En general, el número de caracteres comodín únicos y comodines doble debe ser el mismo para SourcePath y DestinationPath de un solo elemento File.In general, the number of single wildcards and double wildcards must be the same for the SourcePath and DestinationPath of a single File element.

Ejemplo de diseño de empaquetado avanzadoAdvanced packaging layout example

Este es un ejemplo de un diseño más complicado de empaquetado:Here's an example of a more complicated packaging layout:

<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 los elementos ResourcePackage y Optional.This example differs from the simple example with the addition of ResourcePackage and Optional elements.

Los paquetes de recursos se pueden especificar con el elemento ResourcePackage.Resource packages can be specified with the ResourcePackage element. Dentro del ResourcePackage, el elemento Resources debe usarse para especificar los calificadores de recursos del paquete de recursos.Within the ResourcePackage, the Resources element must be used to specify the resource qualifiers of the resource pack. Los calificadores de recursos son los recursos que son compatibles con el paquete de recursos, aquí, podemos ver que hay dos paquetes de recursos definidos y pueden contener los archivos específicos de inglés y francés.The resource qualifiers are the resources that are supported by the resource pack, here, we can see that there are two resource packs defined and they each contain the English and French specific files. Un paquete de recursos puede tener más de un calificador, esto puede hacerse agregando otro elemento Resource dentro de Resources.A resource pack can have more than one qualifier, this can be done by adding another Resource element within Resources. También se debe especificar un recurso predeterminado para la dimensión de recurso si la dimensión existe (dimensiones que son idioma, escala, dxfl).A default resource for the resource dimension must also be specified if the dimension exists (dimensions being language, scale, dxfl). Aquí, podemos ver que el inglés es el idioma predeterminado, lo que significa que para los usuarios que no tienen un idioma del sistema definido en francés, se reservarán para descargar el paquete de recursos de inglés y mostrar en inglés.Here, we can see that English is the default language, meaning that for users that does not have a system language of French set, they will fallback to downloading the English resource pack and display in English.

Cada paquete opcional tiene su propio nombre de familia de paquete distinto y se debe definir con elementos PackageFamily, mientras se especifica el atributo Optional para que sea true .Optional packages each have their own distinct package family names and must be defined with PackageFamily elements, while specifying the Optional attribute to be true. El atributo RelatedSet se usa para especificar si el paquete opcional está dentro del conjunto relacionado (por defecto es true): si el paquete opcional debe actualizarse con el paquete primario.The RelatedSet attribute is used to specify whether the optional package is within the related set (by default this is true) – whether the optional package should be updated with the primary package.

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 a los que se debe hacer referencia en los archivos de lote de aplicaciones que se van a compilar.The PrebuiltPackage element is used to add packages that are not defined in the packaging layout to be included or referenced in the app bundle file(s) to be built. En este caso, se incluye otro paquete DLC opcional aquí para que el archivo del lote de aplicaciones principal pueda hacer referencia a él y que forme parte del conjunto relacionado.In this case, another DLC optional package is being included here so that the primary app bundle file can reference it and have it be part of the related set.

Compilar paquetes de aplicación con un diseño de empaquetado y MakeAppx.exeBuild app packages with a packaging layout and MakeAppx.exe

Una vez que tengas el diseño de empaquetado de tu aplicación, puedes empezar a usar MakeAppx.exe para compilar los paquetes de tu aplicación.Once you have the packaging layout for your app, you can start using MakeAppx.exe to build the packages of your app. Para compilar todos los paquetes definidos en el diseño de empaquetado, usa el comando:To build all of the packages defined in the packaging layout, use the command:

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

Pero, si vas a actualizar tu aplicación y algunos paquetes no contienen ningún archivo modificado, puedes compilar solo los paquetes que has cambiado.But, if you are updating your app and some packages don't contain any changed files, you can build only the packages that have changed. Usando el ejemplo de diseño de empaquetado sencillo de esta página y compilando el paquete de la arquitectura x64, así es cómo aparecería nuestro comando:Using the simple packaging layout example on this page and building the x64 architecture package, this is what our command would look like:

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

La marca /id puede usarse para seleccionar los paquetes que se van a compilar a partir del diseño de empaquetado, correspondiente al atributo ID en el diseño.The /id flag can be used to select the packages to be built from the packaging layout, corresponding to the ID attribute in the layout. La /ip se usa para indicar que la versión anterior de los paquetes se encuentran en este caso.The /ip is used to indicate where the previous version of the packages are in this case. Se debe proporcionar la versión anterior porque el archivo de paquete de aplicaciones todavía debe hacer referencia a la versión anterior del paquete multimedia .The previous version must be provided because the app bundle file still needs to reference the previous version of the Media package. La marca /iv se usa para incrementar automáticamente la versión de los paquetes que se están compilando (en lugar de cambiar la versión en el AppxManifest).The /iv flag is used to automatically increment the version of the packages being built (instead of changing the version in the AppxManifest). Como alternativa, los modificadores /pv y /bv pueden usarse para proporcionar directamente una versión del paquete (para todos los paquetes que se van a crear) y una versión de recopilación (para todas las recopilaciones que se van a crear), respectivamente.Alternatively, the switches /pv and /bv can be used to directly provide a package version (for all packages to be created) and a bundle version (for all bundles to be created), respectively. Con el ejemplo de diseño de empaquetado avanzado en esta página, si quieres compilar la recopilación opcional Themes y el paquete de aplicación Themes.main al que se hace referencia, utilizarías este comando:Using the advanced packaging layout example on this page, if you want to only build the Themes optional bundle and the Themes.main app package that it references, you would use this command:

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

La marca /bc se usa para indicar que los elementos secundarios de la recopilación Themes también se deben compilar (en este caso se compilará Themes.main).The /bc flag is used to denote that the children of the Themes bundle should also be built (in this case Themes.main will be built). La marca /nbp se usa para indicar que el elemento principal de la recopilación Themes no se debe compilar.The /nbp flag is used to denote that the parent of the Themes bundle should not be built. El elemento principal de Themes, que es una recopilación de aplicación opcional, es la recopilación de aplicación principal: MyGame.The parent of Themes, which is an optional app bundle, is the primary app bundle: MyGame. Por lo general para un paquete opcional en un conjunto relacionado, la recopilación de aplicación debe también compilarse para que el paquete opcional sea instalable, ya que al paquete opcional también se hace referencia en la recopilación de aplicación principal cuando se encuentra en un conjunto relacionado (para garantizar el control de versiones entre los paquetes principal y opcionales).Usually for an optional package in a related set, the primary app bundle must also be built for the optional package to be installable, since the optional package is also referenced in the primary app bundle when it is in a related set (to guarantee versioning between the primary and the optional packages). La relación entre principal y secundario entre paquetes se ilustra en el diagrama siguiente:The parent child relationship between packages is illustrated in the following diagram:

Diagrama de diseño de empaquetado