Paketerstellung mit dem VerpackungslayoutPackage creation with the packaging layout

Mit der Einführung von Bestandspaketen stehen Entwicklern nun die Tools zur Verfügung, um mehr Pakete zusätzlich zu mehr Pakettypen zu erstellen.With the introduction of asset packages, developers now have the tools to build more packages in addition to more package types. Wenn eine App größer und komplexer wird, besteht sie oft aus mehreren Paketen, und es wird immer schwieriger, diese Pakete zu verwalten (besonders wenn Sie außerhalb von Visual Studio arbeiten und Mapping-Dateien verwenden).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). Zur Vereinfachung der Verwaltung der Verpackungsstruktur einer App können Sie das von MakeAppx.exe unterstützte Verpackungslayout verwenden.To simplify the management of an app’s packaging structure, you can use the packaging layout supported by MakeAppx.exe.

Das Verpackungslayout ist ein XML-Dokument, das die Verpackungsstruktur der App beschreibt.The packaging layout is a single XML document that describes packaging structure of the app. Es gibt die Bündel einer App („primär” und „optional”), die Pakete in den Bündeln sowie die Dateien in den Paketen an.It specifies the bundles of an app (primary and optional), the packages in the bundles, and the files in the packages. Dateien können aus verschiedenen Ordnern, Laufwerken und Netzwerkadressen ausgewählt werden.Files can be selected from different folders, drives, and network locations. Platzhalter können zum Auswählen oder Ausschließen von Dateien verwendet werden.Wildcards can be used to select or exclude files.

Nachdem das Verpackungslayout für eine App eingerichtet wurde, wird es zusammen mit MakeAppx.exe verwendet, um alle Pakete für eine App in einem einzigen Befehlszeilenaufruf zu erstellen.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. Das Verpackungslayout kann bearbeitet werden, um die Paketstruktur entsprechend Ihren Bereitstellungsanforderungen anzupassen.The packaging layout can be edited to alter the package structure to fit your deployment needs.

Beispiel für ein einfaches VerpackungslayoutSimple packaging layout example

Hier sehen Sie ein Beispiel für ein einfaches Verpackungslayout: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>

Analysieren wir dieses Beispiel, um zu verstehen, wie es funktioniert.Let's break this example down to understand how it works.

PackageFamilyPackageFamily

Mit diesem Paketlayout wird eine einzelne flatApp Bundle Datei mit einem x64-Architektur Paket und einem Medienobjekt Paket erstellt.This packaging layout will create a single flat app bundle file with an x64 architecture package and a “Media” asset package.

Das PackageFamily-Element wird verwendet, um ein App-Bündel zu definieren.The PackageFamily element is used to define an app bundle. Sie müssen das ManifestPath-Attribut verwenden, um für das Bündel eine AppxManifest-Datei bereitzustellen, wobei diese AppxManifest-Datei der AppxManifest-Datei für das Architekturpaket des Bündels entsprechen sollte.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. Das ID-Attribut muss ebenfalls angegeben werden.The ID attribute must also be provided. Dies wird während der Erstellung des Pakets zusammen mit MakeAppx.exe verwendet, damit Sie nur dieses Paket erstellen können, wenn Sie möchten, und das ist der Dateiname des resultierenden Pakets.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. Das FlatBundle-Attribut wird verwendet, um zu beschreiben, welche Art von Bündel Sie erstellen möchten, wobei true für ein flaches Bündel (über das Sie hier mehr lesen können), und false für ein klassisches Bündel steht.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. Das ResourceManager-Attribut wird verwendet, um anzugeben, ob die Ressourcenpakete innerhalb dieses Bündels MRT verwenden, um auf die Dateien zuzugreifen.The ResourceManager attribute is used to specify if the resource packages within this bundle will use MRT in order to access the files. Dies ist standardmäßig true, ab Windows 10, Version 1803, ist es jedoch noch nicht fertig, daher muss dieses Attribut auf false gesetzt werden.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 und AssetPackagePackage and AssetPackage

Innerhalb der PackageFamily sind die Pakete, die ein App-Bündel enthält bzw. Verweise definiert.Within the PackageFamily, the packages that the app bundle contains or references are defined. Hier wird das Architekturpaket (auch als Hauptpaket bezeichnet) mit dem Package-Element, und das Bestandspaket mit dem AssetPackage-Element definiert.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. Das Architekturpaket muss angeben, für welche Architektur das Paket vorgesehen ist, entweder „x64”, „x86”, „arm” oder „neutral”.The architecture package must specify which architecture the package is for, either “x64”, “x86”, “arm”, or “neutral”. Sie können (optional) auch direkt eine AppxManifest-Datei speziell für dieses Paket bereitstellen, indem Sie das ManifestPath-Attribut erneut verwenden.You can also (optionally) directly provide an AppxManifest specifically for this package by using the ManifestPath attribute again. Wenn keine AppxManifest-Datei bereitgestellt wird, wird eine aus der für die PackageFamily bereitgestellten AppxManifest-Datei automatisch generiert.If an AppxManifest is not provided, one will be automatically generated from the AppxManifest provided for the PackageFamily.

Standardmäßig wird für jedes Paket im Bündel eine AppxManifest-Datei generiert.By default and AppxManifest will be generated for every package within the bundle. Für das Bestandspaket können Sie auch das AllowExecution-Attribut festlegen.For the asset package, you can also set the AllowExecution attribute. Dieses Attribut auf false (den Standardwert) festzulegen hilft, die Veröffentlichungszeit Ihrer App zu verkürzen, da die Virenprüfung bei Paketen, die nicht ausgeführt werden müssen, den Veröffentlichungsprozess nicht blockiert (weitere Informationen hierzu finden Sie unter Einführung zu Bestandspaketen).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).

DateienFiles

Innerhalb jeder Paketdefinition können Sie das Datei-Element verwenden, um Dateien auszuwählen, die in diesem Paket enthalten sein sollen.Within each package definition, you can use the File element to select files to be included in this package. Das SourcePath-Attribut gibt an, wo sich die Dateien lokal befinden.The SourcePath attribute is where the files are locally. Sie können Dateien aus verschiedenen Ordnern (durch Angabe von relativen Pfaden), verschiedenen Laufwerken (durch Angabe von absoluten Pfaden) oder sogar Netzwerkfreigaben auswählen (beispielsweise durch Angabe von \\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\*). DestinationPath gibt an, wo die Dateien innerhalb des Pakets, relativ zum Paketstammverzeichnis, gespeichert werden.The DestinationPath is where the files will end up within the package, relative to the package root. ExcludePath kann verwendet werden (anstelle der beiden anderen Attribute), um Dateien von denen auszuschließen, die von den SourcePath-Attributen anderer File-Elemente innerhalb des gleichen Pakets ausgewählt wurden.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.

Jedes File-Element kann zum Auswählen mehrerer Dateien mithilfe von Platzhaltern verwendet werden.Each File element can be used to select multiple files by using wildcards. Im Allgemeinen können einzelne Platzhalter (*) innerhalb des Pfades überall und beliebig oft verwendet werden.In general, single wildcard (*) can be used anywhere within the path any number of times. Ein Platzhalter entspricht jedoch nur den Dateien in einem Ordner und nicht in Unterordnern.However, a single wildcard will only match the files within a folder and not any subfolders. Beispielsweise kann C:\MyGame\*\* in SourcePath zum Auswählen der Dateien C:\MyGame\Audios\UI.mp3 und C:\MyGame\Videos\intro.mp4 verwendet werden, es kann jedoch nicht C:\MyGame\Audios\Level1\warp.mp3 auswählen.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. Der doppelte Platzhalter (**) kann auch anstelle von Ordner- oder Dateinamen verwendet werden, um beliebige Zeichenfolgen rekursiv zu ersetzen (jedoch nicht neben Teilnamen).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). Beispielsweise kann C:\MyGame\**\Level1\**``C:\MyGame\Audios\Level1\warp.mp3 und C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4 auswählen.For example, C:\MyGame\**\Level1\** can select C:\MyGame\Audios\Level1\warp.mp3 and C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4. Platzhalter können auch verwendet werden, um Dateinamen im Rahmen des Verpackungsprozesses direkt zu ändern, wenn die Platzhalter an verschiedenen Stellen zwischen Quelle und Ziel verwendet werden.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. Wenn zum Beispiel C:\MyGame\Audios\* für SourcePath und Sound\copy_* für DestinationPath steht, kann C:\MyGame\Audios\UI.mp3 ausgewählt werden und wird im Paket als Sound\copy_UI.mp3 angezeigt.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. Im Allgemeinen muss die Anzahl der einfachen Platzhalter und doppelten Platzhalter für SourcePath und DestinationPath eines einzelnen File-Elements identisch sein.In general, the number of single wildcards and double wildcards must be the same for the SourcePath and DestinationPath of a single File element.

Beispiel für ein erweitertes VerpackungslayoutAdvanced packaging layout example

Hier sehen Sie ein Beispiel für ein komplizierteres Verpackungslayout: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>

Dieses Beispiel unterscheidet sich vom einfachen Beispiel durch das Hinzufügen der Elemente ResourcePackage und Optional.This example differs from the simple example with the addition of ResourcePackage and Optional elements.

Ressourcenpakete können mit dem ResourcePackage-Element angegeben werden.Resource packages can be specified with the ResourcePackage element. Innerhalb von ResourcePackage muss das Resources-Element für die Angabe der Ressourcenbezeichner des Ressourcenpakets verwendet werden.Within the ResourcePackage, the Resources element must be used to specify the resource qualifiers of the resource pack. Die Ressourcenbezeichner sind die Ressourcen, die vom Ressourcenpaket unterstützt werden. Hier sehen wir, dass zwei Ressourcenpakete definiert sind, die jeweils die sprachspezifischen Dateien für Englisch und Französisch enthalten.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. Ein Ressourcenpaket kann mehrere Bezeichner haben. Fügen Sie hierzu ein weiteres Resource-Element in Resources hinzu.A resource pack can have more than one qualifier, this can be done by adding another Resource element within Resources. Außerdem muss eine Standardressource für die Ressourcendimension angegeben werden, wenn die Dimension (Sprache, Skalierung und dxfl) vorhanden ist.A default resource for the resource dimension must also be specified if the dimension exists (dimensions being language, scale, dxfl). Hier sehen wir, dass Englisch die Standardsprache ist, was für Benutzer, die Französisch nicht als Systemsprache festgelegt haben, bedeutet, dass sie das englische Ressourcenpaket herunterladen und zur Anzeige in Englisch wechseln müssen.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.

Optionale Pakete besitzen jeweils ihre eigenen, eindeutigen Paketfamiliennamen und müssen mit PackageFamily-Elementen definiert werden, wenn das Optional-Attribut als true angegeben wird.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. Das RelatedSet-Attribut wird verwendet, um anzugeben, ob sich das optionale Paket innerhalb des zugehörigen Sets befindet (standardmäßig ist dieser Wert „true”), und ob das optionale Paket mit dem primären Paket aktualisiert werden soll.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.

Das prebuiltpackage -Element wird zum Hinzufügen von Paketen verwendet, die nicht im Paket Layout definiert sind und in die zu erstellenden App Bundle Dateien eingeschlossen werden sollen.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. In diesem Fall wird hier ein weiteres optionales DLC-Paket eingefügt, sodass die primäre App Bundle Datei auf die Datei verweisen und Sie in der zugehörigen Gruppe enthalten kann.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.

Erstellen von App-Paketen mit einem Verpackungslayout und MakeAppx.exeBuild app packages with a packaging layout and MakeAppx.exe

Sobald Sie das Verpackungslayout für Ihre App haben, können Sie MakeAppx.exe verwenden, um die Pakete Ihrer App zu erstellen.Once you have the packaging layout for your app, you can start using MakeAppx.exe to build the packages of your app. Verwenden Sie den folgenden Befehl, um alle im Verpackungslayout definierten Pakete zu erstellen:To build all of the packages defined in the packaging layout, use the command:

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

Wenn Sie jedoch Ihre App aktualisieren, und einige Pakete keine geänderten Dateien enthalten, können Sie nur die Pakete erstellen, die geändert wurden.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. Bei Verwendung des einfachen Beispiels für ein Verpackungslayout auf dieser Seite und beim Erstellen des x64-Architekturpakets würde der Befehl folgendermaßen aussehen: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

Mit dem /id-Kennzeichen können die zu erstellenden Pakete aus dem Verpackungslayout entsprechend dem ID-Attribut im Layout ausgewählt werden.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. /ip wird verwendet, um anzugeben, wo sich in diesem Fall die früheren Versionen der Pakete befinden.The /ip is used to indicate where the previous version of the packages are in this case. Die vorherige Version muss bereitgestellt werden, da die APP Bundle Datei immer noch auf die vorherige Version des Medien Pakets verweisen muss.The previous version must be provided because the app bundle file still needs to reference the previous version of the Media package. Mit dem /iv-Kennzeichen wird die Version der zu erstellenden Pakete automatisch erhöht (anstatt die Version in der AppxManifest-Datei zu ändern).The /iv flag is used to automatically increment the version of the packages being built (instead of changing the version in the AppxManifest). Sie können auch die Switches /pv und /bv verwenden, um eine Paketversion (für alle zu erstellenden Pakete) bzw. eine Bündelversion (für alle zu erstellenden Bündel), direkt bereitzustellen.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. Verwenden Sie diesen Befehl, wenn Sie mithilfe des erweiterten Verpackungslayoutbeispiels auf dieser Seite nur das optionale Bündel Designs und das App-Paket Themes.main, auf das es verweist, erstellen möchten: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

Das /bc-Kennzeichen wird verwendet, um anzugeben, dass die untergeordneten Elemente des Designs-Bündels ebenfalls erstellt werden sollen (in diesem Fall wird Themes.main erstellt).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). Das /nbp-Kennzeichen gibt an, dass das übergeordnete Element des Designs-Bündels nicht erstellt werden soll.The /nbp flag is used to denote that the parent of the Themes bundle should not be built. Das übergeordnete Element von Designs, bei dem es sich um ein optionales App-Bündel handelt, ist das primäre App-Bündel: MyGame.The parent of Themes, which is an optional app bundle, is the primary app bundle: MyGame. In der Regel muss für ein optionales Paket in einem zugehörigen Set auch das primäre App-Bündel erstellt werden, damit das optionale Paket installiert werden kann, da auf das optionale Paket auch im primären App-Bündel verwiesen wird, wenn es sich in einem zugehörigen Set befindet (um die Versionierung zwischen primärem und optionalem Paket zu gewährleisten).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). Das folgende Diagramm veranschaulicht die über- und untergeordnete Beziehung zwischen Paketen.The parent child relationship between packages is illustrated in the following diagram:

Verpackungslayout-Diagramm