Paketerstellung mit dem Verpackungslayout
Mit der Einführung von Bestandspaketen verfügen Entwickler jetzt über die Tools zum Erstellen weiterer Pakete zusätzlich zu weiteren Pakettypen. Wenn eine App größer und komplexer wird, besteht sie häufig aus mehr Paketen, und die Schwierigkeit beim Verwalten dieser Pakete wird erhöht (insbesondere, wenn Sie außerhalb von Visual Studio erstellen und Zuordnungsdateien verwenden). Um die Verwaltung der Verpackungsstruktur einer App zu vereinfachen, können Sie das von MakeAppx.exe unterstützte Verpackungslayout verwenden.
Das Verpackungslayout ist ein einzelnes XML-Dokument, das die Verpackungsstruktur der App beschreibt. Es gibt die Bündel einer App (primär und optional), die Pakete in den Bündeln und die Dateien in den Paketen an. Dateien können aus verschiedenen Ordnern, Laufwerken und Netzwerkspeicherorten ausgewählt werden. Wild Karte können zum Auswählen oder Ausschließen von Dateien verwendet werden.
Nachdem das Verpackungslayout für eine App eingerichtet wurde, wird es mit MakeAppx.exe verwendet, um alle Pakete für eine App in einem einzigen Befehlszeilenaufruf zu erstellen. Das Verpackungslayout kann bearbeitet werden, um die Paketstruktur an Ihre Bereitstellungsanforderungen anzupassen.
Beispiel für ein einfaches Verpackungslayout
Hier sehen Sie ein Beispiel dafür, wie ein einfaches Verpackungslayout aussieht:
<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>
Lassen Sie uns dieses Beispiel aufschlüsseln, um zu verstehen, wie es funktioniert.
PackageFamily
Dieses Paketlayout erstellt eine einzelne flache App-Bündeldatei mit einem x64-Architekturpaket und einem "Media"-Objektpaket.
Das PackageFamily-Element wird verwendet, um ein App-Bündel zu definieren. Sie müssen das ManifestPath-Attribut verwenden, um ein AppxManifest für das Bundle bereitzustellen, das AppxManifest sollte dem AppxManifest für das Architekturpaket des Bundles entsprechen. Das ID-Attribut muss ebenfalls angegeben werden. Dies wird während der Paketerstellung mit MakeAppx.exe verwendet, sodass Sie nur dieses Paket erstellen können, wenn Sie möchten, und dies ist der Dateiname des resultierenden Pakets. Das FlatBundle-Attribut wird verwendet, um zu beschreiben, welche Art von Bündel Sie erstellen möchten, true für ein flaches Bündel (das Sie hier lesen können) und "false " für ein klassisches Bündel. Das ResourceManager-Attribut wird verwendet, um anzugeben, ob die Ressourcenpakete in diesem Bundle MRT verwenden, um auf die Dateien zuzugreifen. Dies ist standardmäßig "true", aber ab Windows 10, Version 1803, ist dies noch nicht bereit, sodass dieses Attribut auf "false" festgelegt werden muss.
Package and AssetPackage
Innerhalb der PackageFamily werden die Pakete, die das App-Bündel enthält, oder Verweise definiert. Hier wird das Architekturpaket (auch als Standard-Paket bezeichnet) mit dem Package-Element definiert, und das Objektpaket wird mit dem AssetPackage-Element definiert. Das Architekturpaket muss angeben, für welche Architektur das Paket bestimmt ist, entweder "x64", "x86", "arm" oder "neutral". Sie können auch (optional) ein AppxManifest speziell für dieses Paket bereitstellen, indem Sie das ManifestPath-Attribut erneut verwenden. Wenn kein AppxManifest bereitgestellt wird, wird eine automatisch aus dem appxManifest generiert, das für die PackageFamily bereitgestellt wird.
Standardmäßig wird AppxManifest für jedes Paket innerhalb des Bundles generiert. Für das Objektpaket können Sie auch das AllowExecution-Attribut festlegen. Wenn Sie diesen Wert auf "false" festlegen (Standardeinstellung), wird die Veröffentlichungszeit für Ihre App verringert, da Pakete, die nicht ausgeführt werden müssen, den Veröffentlichungsprozess nicht blockieren (Weitere Informationen hierzu finden Sie unter Einführung in Bestandspakete).
Dateien
In jeder Paketdefinition können Sie das File-Element verwenden, um Dateien auszuwählen, die in dieses Paket eingeschlossen werden sollen. Das SourcePath-Attribut ist der Ort, an dem sich die Dateien lokal befinden. Sie können Dateien aus verschiedenen Ordnern auswählen (indem Sie relative Pfade bereitstellen), verschiedene Laufwerke (indem Sie absolute Pfade bereitstellen) oder sogar Netzwerkfreigaben (indem Sie etwas wie \\myshare\myapp\*
angeben). ZielPath ist der Ort, an dem die Dateien innerhalb des Pakets relativ zum Paketstamm enden. ExcludePath kann (anstelle der anderen beiden Attribute) verwendet werden, um Dateien auszuwählen, die von den SourcePath-Attributen anderer Dateielemente innerhalb desselben Pakets ausgeschlossen werden sollen.
Jedes File-Element kann verwendet werden, um mehrere Dateien mithilfe von Wild Karte auszuwählen. Im Allgemeinen können einzelne Wild Karte (*
) überall innerhalb des Pfads beliebig oft verwendet werden. Ein einzelnes Wild Karte entspricht jedoch nur den Dateien innerhalb eines Ordners und nicht mit Unterordnern. Beispielsweise kann in SourcePath verwendet werden, C:\MyGame\*\*
um die Dateien C:\MyGame\Audios\UI.mp3
auszuwählen, C:\MyGame\Videos\intro.mp4
aber es kann nicht ausgewählt C:\MyGame\Audios\Level1\warp.mp3
werden. Die doppelten Platzhalter Karte (**
) können auch anstelle von Ordner- oder Dateinamen verwendet werden, um rekursiv etwas abzugleichen (aber nicht neben Teilnamen). Kann z. B C:\MyGame\**\Level1\**
. auswählen C:\MyGame\Audios\Level1\warp.mp3
und C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4
. Wild Karte s können auch verwendet werden, um Dateinamen im Rahmen des Verpackungsvorgangs direkt zu ändern, wenn die Wild Karte an unterschiedlichen Stellen zwischen Quelle und Ziel verwendet werden. Wenn Sie z. BC:\MyGame\Audios\*
. sourcePath und Sound\copy_*
DestinationPath verwenden, können sie auswählen C:\MyGame\Audios\UI.mp3
und im Paket Sound\copy_UI.mp3
als angezeigt werden lassen. Im Allgemeinen muss die Anzahl einzelner Platzhalter Karte und doppelter Platzhalter identisch sein Karte für den SourcePath und DestinationPath eines einzelnen Dateielements.
Beispiel für ein erweitertes Verpackungslayout
Hier ist ein Beispiel für ein komplizierteres Verpackungslayout:
<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 mit dem Hinzufügen von ResourcePackage - und Optional-Elementen .
Ressourcenpakete können mit dem ResourcePackage-Element angegeben werden. Innerhalb des ResourcePackage muss das Resources-Element verwendet werden, um die Ressourcenqualifizierer des Ressourcenpakets anzugeben. Die Ressourcenqualifizierer sind die Ressourcen, die vom Ressourcenpaket unterstützt werden. Hier können wir sehen, dass zwei Ressourcenpakete definiert sind und sie jeweils die englischsprachigen und französischen spezifischen Dateien enthalten. Ein Ressourcenpaket kann mehrere Qualifizierer haben, dies kann durch Hinzufügen eines anderen Ressourcenelements innerhalb von Resources erfolgen. Eine Standardressource für die Ressourcendimension muss auch angegeben werden, wenn die Dimension vorhanden ist (Dimensionen mit Sprache, Skalierung, DXFL). Hier können wir sehen, dass Englisch die Standardsprache ist, was bedeutet, dass für Benutzer, die keine Systemsprache französisch festgelegt haben, sie fallbacken werden, um das englische Ressourcenpaket herunterzuladen und in Englisch anzuzeigen.
Optionale Pakete weisen jeweils eigene eindeutige Paketfamiliennamen auf und müssen mit PackageFamily-Elementen definiert werden, wobei das optionale Attribut auf "true" festgelegt wird. Das RelatedSet-Attribut wird verwendet, um anzugeben, ob sich das optionale Paket innerhalb des zugehörigen Satzes befindet (standardmäßig ist dies "true") – ob das optionale Paket mit dem primären Paket aktualisiert werden soll.
Das PrebuiltPackage-Element wird verwendet, um Pakete hinzuzufügen, die nicht im Verpackungslayout definiert sind, um in die zu erstellenden App-Bündeldatei(n) eingeschlossen oder referenziert zu werden. In diesem Fall wird ein weiteres optionales DLC-Paket hier enthalten, damit die primäre App-Bundledatei darauf verweisen kann und teil des zugehörigen Satzes ist.
Erstellen von App-Paketen mit einem Verpackungslayout und MakeAppx.exe
Sobald Sie über das Verpackungslayout für Ihre App verfügen, können Sie mit makeAppx.exe beginnen, um die Pakete Ihrer App zu erstellen. Verwenden Sie den Befehl, um alle im Verpackungslayout definierten Pakete zu erstellen:
MakeAppx.exe build /f PackagingLayout.xml /op OutputPackages\
Wenn Sie Ihre App jedoch aktualisieren und einige Pakete keine geänderten Dateien enthalten, können Sie nur die Pakete erstellen, die geändert wurden. Mithilfe des einfachen Verpackungslayoutbeispiels auf dieser Seite und dem Erstellen des x64-Architekturpakets würde unser Befehl wie folgt aussehen:
MakeAppx.exe build /f PackagingLayout.xml /id "x64" /ip PreviousVersion\ /op OutputPackages\ /iv
Das /id
Kennzeichen kann verwendet werden, um die Pakete auszuwählen, die aus dem Verpackungslayout erstellt werden sollen, das dem ID-Attribut im Layout entspricht. Dies /ip
wird verwendet, um anzugeben, wo sich die vorherige Version der Pakete in diesem Fall befindet. Die vorherige Version muss bereitgestellt werden, da die App-Bundledatei weiterhin auf die vorherige Version des Medienpakets verweisen muss. Das /iv
Flag wird verwendet, um die Version der zu erstellenden Pakete automatisch zu erhöhen (anstatt die Version im AppxManifest zu ändern). Alternativ können die Switches /pv
und /bv
verwendet werden, um direkt eine Paketversion (für alle zu erstellenden Pakete) und eine Bundleversion (für alle zu erstellenden Bündel) bereitzustellen.
Wenn Sie auf dieser Seite nur das optionale Bundle "Designs" und das App-Paket "Themes.Standard" erstellen möchten, das auf dieses Layoutbeispiel verweist, verwenden Sie diesen Befehl:
MakeAppx.exe build /f PackagingLayout.xml /id "Themes" /op OutputPackages\ /bc /nbp
Die /bc
Kennzeichnung wird verwendet, um anzugeben, dass die untergeordneten Elemente des Designs-Bündels ebenfalls erstellt werden sollen (in diesem Fall "Themes.Standard" wird erstellt). Die /nbp
Kennzeichnung wird verwendet, um anzugeben, dass das übergeordnete Element des Designs-Bündels nicht erstellt werden soll. Das übergeordnete Element von Designs, bei dem es sich um ein optionales App-Bündel handelt, ist das primäre App-Bündel: MyGame. In der Regel muss für ein optionales Paket in einem verwandten Satz das primäre App-Bündel auch erstellt werden, damit das optionale Paket installierbar ist, da das optionale Paket auch im primären App-Bündel referenziert wird, wenn es sich in einem verwandten Satz befindet (um die Versionsverwaltung zwischen dem primären und den optionalen Paketen zu gewährleisten). Die Beziehung zwischen den übergeordneten untergeordneten Elementen zwischen Paketen wird im folgenden Diagramm veranschaulicht: