Freigeben über


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.exeunterstü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. Mit Wildcards können Dateien ausgewählt oder ausgeschlossen 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.

Paketfamilie

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

Paket und Asset-Paket

Innerhalb der PackageFamily werden die Pakete und Verweise definiert, die das App-Bündel enthält oder auf die es verweist. Hier wird das Architekturpaket (auch als Hauptpaket 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 dieser Wert auf false (Standardeinstellung) gesetzt wird, kann die Veröffentlichungszeit Ihrer App verkürzt werden, da Pakete, die nicht ausgeführt werden müssen, die Virusprüfung nicht den Veröffentlichungsprozess blockieren. Weitere Informationen finden Sie unter Einführung in Asset-Pakete.

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 Dateielement kann verwendet werden, um mehrere Dateien mithilfe von Wildcards auszuwählen. Im Allgemeinen kann ein einzelner Platzhalter (*) an beliebiger Stelle innerhalb des Pfads beliebig oft verwendet werden. Ein einzelner Wildcard passt jedoch nur auf die Dateien in einem Ordner und nicht auf Unterordner. Beispielsweise kann C:\MyGame\*\* im SourcePath verwendet werden, um die Dateien C:\MyGame\Audios\UI.mp3 und C:\MyGame\Videos\intro.mp4 auszuwählen, aber es kann C:\MyGame\Audios\Level1\warp.mp3 nicht auswählen. Der doppelte Platzhalter (**) kann auch anstelle von Ordner- oder Dateinamen verwendet werden, um etwas rekursiv abzugleichen (aber nicht neben Teilnamen). Zum Beispiel kann C:\MyGame\**\Level1\** auswählen C:\MyGame\Audios\Level1\warp.mp3 und 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. Zum Beispiel kann C:\MyGame\Audios\* für SourcePath und Sound\copy_* für DestinationPath ausgewählt werden und im Paket als C:\MyGame\Audios\UI.mp3 erscheinen. Im Allgemeinen muss die Anzahl einzelner Platzhalter und doppelter Platzhalter für sourcePath und DestinationPath eines einzelnen File-Elements identisch sein.

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 angegeben werden, wenn die Dimension vorhanden ist (Dimensionen wie Sprache, Skalierung, DXFL). Hier können wir sehen, dass Englisch die Standardsprache ist. Das bedeutet, dass Benutzer, die nicht Französisch als Systemsprache festgelegt haben, auf das Herunterladen des englischen Ressourcenpakets zurückgreifen und die Anzeige auf Englisch umschalten.

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 hinzugefügt, damit die primäre App-Bundle-Datei darauf verweisen kann und Teil des zusammengehörigen Sets ist.

App-Pakete mit einem Verpackungslayout und MakeAppx.exe erstellen

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 Themes und das Themes.main-App-Paket erstellen möchten, auf das es verweist, verwenden Sie den folgenden Befehl:

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

Das /bc Kennzeichen wird verwendet, um anzugeben, dass die untergeordneten Elemente des Themen-Bündels ebenfalls erstellt werden sollen (in diesem Fall wird Themes.main erstellt). Die /nbp Kennzeichnung wird verwendet, um anzugeben, dass das übergeordnete Element des Themes-Bündels nicht erstellt werden soll. Das übergeordnete Paket von Themen, 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 Eltern-Kind-Beziehung der Pakete wird im folgenden Diagramm veranschaulicht.

Verpackungslayoutdiagramm