Paketerstellung mit dem Verpackungslayout

Mit der Einführung von Ressourcenpaketen verfügen Entwickler jetzt über die Tools, um zusätzlich zu mehr Pakettypen weitere Pakete zu erstellen. Wenn eine App größer und komplexer wird, besteht sie häufig aus mehr Paketen, und die Probleme bei der Verwaltung dieser Pakete werden zunehmen (insbesondere, wenn Sie außerhalb von Visual Studio erstellen und Zuordnungsdateien verwenden). Um die Verwaltung der Paketstruktur einer App zu vereinfachen, können Sie das Paketlayout verwenden, das von MakeAppx.exe.

Das Paketlayout ist ein einzelnes XML-Dokument, das die Paketstruktur der App beschreibt. Sie gibt die Pakete einer App (primär und optional), die Pakete in den Paketen und die Dateien in den Paketen an. Dateien können aus verschiedenen Ordnern, Laufwerken und Netzwerkstandorten ausgewählt werden. Platzhalter können verwendet werden, um Dateien auszuwählen oder auszuschließen.

Nachdem das Paketlayout 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 Paketlayout kann bearbeitet werden, um die Paketstruktur an Ihre Bereitstellungsanforderungen anzupassen.

Beispiel für einfaches Paketlayout

Hier sehen Sie ein Beispiel für ein einfaches Paketlayout:

<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 aufarbeiten, um zu verstehen, wie es funktioniert.

PackageFamily

Dieses Paketlayout erstellt eine einzelne Flat-App-Paketdatei mit einem x64-Architekturpaket und einem Medienmedienpaket.

Das PackageFamily-Element wird verwendet, um ein App-Paket zu definieren. Sie müssen das ManifestPath-Attribut verwenden, um ein AppxManifest für das Paket zur Verfügung zu stellen. Das AppxManifest sollte dem AppxManifest für das Architekturpaket des Pakets entsprechen. Das ID-Attribut muss ebenfalls bereitgestellt werden. Dies wird bei MakeAppx.exe Paketerstellung verwendet, sodass Sie nur dieses Paket erstellen können, wenn Sie möchten. Dies ist der Dateiname des resultierenden Pakets. Das FlatBundle-Attribut wird verwendet, um zu beschreiben, welche Art von Paket Sie erstellen möchten, true für ein flaches Paket (das Sie hier mehr erfahren können) und FALSE für ein klassisches Paket. Das ResourceManager-Attribut wird verwendet, um anzugeben, ob die Ressourcenpakete in diesem Paket MRT verwenden, um auf die Dateien zu zugreifen. Dies ist standardmäßig "true". Ab Windows 10 Version 1803 ist dies jedoch noch nicht bereit, sodass dieses Attribut auf false festgelegt werden muss.

Paket und AssetPackage

Innerhalb von PackageFamily werden die Pakete definiert, die das App-Paket enthält oder auf die verwiesen wird. Hier wird das Architekturpaket (auch als Hauptpaket bezeichnet) mit dem Package-Element definiert, und das Ressourcenpaket wird mit dem AssetPackage-Element definiert. Das Architekturpaket muss angeben, für welche Architektur das Paket ist, entweder "x64", "x86", "arm" oder "neutral". Sie können auch (optional) direkt ein AppxManifest speziell für dieses Paket bereitstellen, indem Sie das ManifestPath-Attribut erneut verwenden. Wenn kein AppxManifest bereitgestellt wird, wird automatisch ein AppxManifest generiert, das für PackageFamily bereitgestellt wird.

Standardmäßig werden und AppxManifest für jedes Paket innerhalb des Pakets generiert. Für das Ressourcenpaket können Sie auch das AllowExecution-Attribut festlegen. Wenn Sie diese Einstellung 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 finden Sie unter Einführungin Assetpakete).

Files

Innerhalb jeder Paketdefinition können Sie das File-Element verwenden, um Dateien auszuwählen, die in dieses Paket aufgenommen werden sollen. Das SourcePath-Attribut ist der Ort, an dem sich die Dateien befinden. Sie können Dateien aus verschiedenen Ordnern auswählen (indem Sie relative Pfade, verschiedene Laufwerke (durch Angabe absoluter Pfade) oder sogar Netzwerkfreigaben (z. B. ) \\myshare\myapp\* bereitstellen. Der DestinationPath ist der Ort, an dem die Dateien im Paket gespeichert werden, relativ zum Paketstamm. ExcludePath kann (anstelle der anderen beiden Attribute) verwendet werden, um Dateien auszuwählen, die von denjenigen ausgeschlossen werden sollen, die von den SourcePath-Attributen anderer File-Elemente innerhalb desselben Pakets ausgewählt werden sollen.

Jedes File-Element kann verwendet werden, um mehrere Dateien mithilfe von Platzhaltern auszuwählen. Im Allgemeinen kann ein einzelner Platzhalter ( ) überall innerhalb des Pfads so oft * wie möglich verwendet werden. Ein einzelner Platzhalter wird jedoch nur mit den Dateien innerhalb eines Ordners und nicht mit unteren Ordnern übereinstimmen. Beispielsweise kann C:\MyGame\*\* in SourcePath verwendet werden, um die Dateien und C:\MyGame\Audios\UI.mp3 C:\MyGame\Videos\intro.mp4 auszuwählen, aber es kann nicht ausgewählt C:\MyGame\Audios\Level1\warp.mp3 werden. Der doppelte Platzhalter ( ) kann auch statt Ordner- oder Dateinamen verwendet werden, um rekursiv mit etwas zu übereinstimmen (aber nicht neben ** Teilnamen). kann z. C:\MyGame\**\Level1\** B. C:\MyGame\Audios\Level1\warp.mp3 und C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4 auswählen. Platzhalter können auch verwendet werden, um Dateinamen im Rahmen des Paketprozesses direkt zu ändern, wenn die Platzhalter an verschiedenen Stellen zwischen Quelle und Ziel verwendet werden. Wenn sie z. C:\MyGame\Audios\* B. für SourcePath und Sound\copy_* für DestinationPath verwenden, kann diese Option auswählen und im C:\MyGame\Audios\UI.mp3 Paket als angezeigt Sound\copy_UI.mp3 werden. Im Allgemeinen muss die Anzahl einzelner Platzhalter und doppelter Platzhalter für SourcePath und DestinationPath eines einzelnen File-Elements identisch sein.

Beispiel für erweitertes Paketlayout

Hier sehen Sie ein Beispiel für ein komplizierteres Paketlayout:

<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 Addition 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 sehen wir, dass zwei Ressourcenpakete definiert sind und sie jeweils die englischen und französischen spezifischen Dateien enthalten. Ein Ressourcenpaket kann über mehrere Qualifizierer verfügen. Dies kann durch Hinzufügen eines weiteren Resource-Elements in Resources erfolgen. Eine Standardressource für die Ressourcendimension muss auch angegeben werden, wenn die Dimension vorhanden ist (Dimensionen sind Language, Scale, dxfl). Hier sehen wir, dass Englisch die Standardsprache ist. Dies bedeutet, dass Benutzer, für die keine Systemsprache Französisch festgelegt ist, ein Fallback auf das Herunterladen des englischen Ressourcenpakets und die Anzeige auf Englisch verwenden.

Optionale Pakete verfügen jeweils über eigene unterschiedliche Paketfamiliennamen und müssen mit PackageFamily-Elementen definiert werden, während das Optional-Attribut als true angegeben wird. Das RelatedSet-Attribut wird verwendet, um anzugeben, ob sich das optionale Paket innerhalb des zugehörigen Sets befindet (standardmäßig ist dies TRUE), d. h., ob das optionale Paket mit dem primären Paket aktualisiert werden soll.

Das PrebuiltPackage-Element wird verwendet, um Pakete hinzuzufügen, die nicht im Paketlayout definiert sind, um in die zu erstellenden App-Paketdatei(en) eingeschlossen oder darauf verwiesen zu werden. In diesem Fall wird hier ein weiteres optionales DLC-Paket eingeschlossen, damit die primäre App-Bündeldatei darauf verweisen und sie teil des zugehörigen Bündels sein kann.

Erstellen von App-Paketen mit einem Paketlayout und MakeAppx.exe

Sobald Sie über das Paketlayout für Ihre App verfügen, können Sie mit MakeAppx.exe, um die Pakete Ihrer App zu erstellen. Verwenden Sie den Befehl , um alle pakete zu erstellen, die im Paketlayout definiert sind:

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 geänderten Pakete erstellen. Mithilfe des einfachen Paketlayoutbeispiels auf dieser Seite und dem Erstellen des x64-Architekturpakets würde unser Befehl wie hier aussehen:

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

Das -Flag kann verwendet werden, um die Pakete auszuwählen, die aus dem Paketlayout erstellt werden sollen, das dem /id ID-Attribut im Layout entspricht. Wird /ip verwendet, um anzugeben, wo sich die vorherige Version der Pakete in diesem Fall befindet. Die vorherige Version muss bereitgestellt werden, da die App-Bündeldatei weiterhin auf die vorherige Version des Medienpakets verweisen muss. Das -Flag wird verwendet, um die Version der zu erstellenden Pakete automatisch zu erhöhen (anstatt die Version /iv im AppxManifest zu ändern). Alternativ können die Schalter und verwendet werden, um direkt eine Paketversion (für alle zu erstellenden Pakete) bzw. eine Paketversion (für alle zu erstellenden /pv /bv Pakete) zur Verfügung zu stellen. Wenn Sie das erweiterte Paketlayoutbeispiel auf dieser Seite verwenden, verwenden Sie den folgenden Befehl, wenn Sie nur das optionale Themes-Paket und das Themes.main-App-Paket erstellen möchten, auf das es verweist:

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

Das -Flag wird verwendet, um zu kennzeichnen, dass die unteren Bündel des Designs-Pakets ebenfalls erstellt werden sollen (in diesem Fall /bc wird Themes.main erstellt). Das /nbp -Flag wird verwendet, um zu kennzeichnen, dass das übergeordnete Element des Designs-Bündels nicht erstellt werden soll. Das übergeordnete Element von Themes, bei dem es sich um ein optionales App-Paket handelt, ist das primäre App-Paket: MyGame. In der Regel muss für ein optionales Paket in einem zugehörigen Satz auch das primäre App-Paket erstellt werden, damit das optionale Paket installiert werden kann, da auf das optionale Paket auch im primären App-Paket verwiesen wird, wenn es sich in einem zugehörigen Satz befindet (um die Versionserstellbarung zwischen dem primären und den optionalen Paketen zu gewährleisten). Die Beziehung zwischen den übergeordneten untergeordneten Paketen wird im folgenden Diagramm veranschaulicht:

Paketlayoutdiagramm