Creazione del pacchetto con il layout di creazione di pacchetti

Con l'introduzione dei pacchetti di asset, gli sviluppatori hanno ora gli strumenti per creare più pacchetti oltre a più tipi di pacchetto. Man mano che un'app diventa più grande e complessa, spesso sarà costituita da più pacchetti e la difficoltà di gestione di questi pacchetti aumenterà (soprattutto se si compilano all'esterno di Visual Studio e si usano file di mapping). Per semplificare la gestione della struttura di creazione di pacchetti di un'app, è possibile usare il layout dei pacchetti supportato da MakeAppx.exe.

Il layout della creazione di pacchetti è un singolo documento XML che descrive la struttura di creazione di pacchetti dell'app. Specifica i bundle di un'app (primaria e facoltativa), i pacchetti nei bundle e i file nei pacchetti. I file possono essere selezionati da cartelle, unità e percorsi di rete diversi. I caratteri jolly possono essere usati per selezionare o escludere file.

Dopo aver configurato il layout di creazione dei pacchetti per un'app, viene usato con MakeAppx.exe per creare tutti i pacchetti per un'app in una singola chiamata da riga di comando. Il layout dei pacchetti può essere modificato per modificare la struttura del pacchetto in base alle esigenze di distribuzione.

Esempio di layout di creazione di pacchetti semplice

Di seguito è riportato un esempio dell'aspetto di un semplice layout di creazione di pacchetti:

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

Si esaminerà ora questo esempio per comprendere il funzionamento.

PackageFamily

Questo layout di creazione di pacchetti creerà un singolo file bundle dell'app flat con un pacchetto di architettura x64 e un pacchetto di asset "Media".

L'elemento PackageFamily viene usato per definire un bundle dell'app. È necessario usare l'attributo ManifestPath per fornire un Oggetto AppxManifest per il bundle. AppxManifest deve corrispondere all'AppxManifest per il pacchetto di architettura del bundle. È necessario specificare anche l'attributo ID . Questa operazione viene utilizzata con MakeAppx.exe durante la creazione del pacchetto in modo che sia possibile creare solo questo pacchetto se si desidera e questo sarà il nome file del pacchetto risultante. L'attributo FlatBundle viene usato per descrivere il tipo di bundle che si vuole creare, true per un bundle flat (che è possibile leggere qui) e false per un bundle classico. L'attributo ResourceManager viene usato per specificare se i pacchetti di risorse all'interno di questo bundle useranno MRT per accedere ai file. Questo valore è true per impostazione predefinita, ma a partire da Windows 10, versione 1803, non è ancora pronto, quindi questo attributo deve essere impostato su false.

Pacchetto e AssetPackage

All'interno di PackageFamily, vengono definiti i pacchetti contenuti nel bundle dell'app o i riferimenti. In questo caso, il pacchetto di architettura (detto anche pacchetto principale) viene definito con l'elemento Package e il pacchetto di asset viene definito con l'elemento AssetPackage . Il pacchetto di architettura deve specificare l'architettura per cui si trova il pacchetto, ovvero "x64", "x86", "arm" o "neutral". È anche possibile specificare (facoltativamente) direttamente un Oggetto AppxManifest specifico per questo pacchetto usando di nuovo l'attributo ManifestPath . Se non viene specificato un AppxManifest , ne verrà generato automaticamente uno da AppxManifest fornito per PackageFamily.

Per impostazione predefinita, AppxManifest verrà generato per ogni pacchetto all'interno del bundle. Per il pacchetto di asset, è anche possibile impostare l'attributo AllowExecution . L'impostazione di questo valore su false (impostazione predefinita) consentirà di ridurre il tempo di pubblicazione per l'app, perché i pacchetti che non devono essere eseguiti non avranno il blocco dell'analisi virus per il processo di pubblicazione (per altre informazioni, vedere Introduzione ai pacchetti di asset).

File

All'interno di ogni definizione del pacchetto, è possibile usare l'elemento File per selezionare i file da includere in questo pacchetto. L'attributo SourcePath è il percorso in cui si trovano i file in locale. È possibile selezionare i file da cartelle diverse (fornendo percorsi relativi), unità diverse (fornendo percorsi assoluti) o persino condivisioni di rete (fornendo qualcosa di simile \\myshare\myapp\*a ). DestinationPath è la posizione in cui i file finiranno all'interno del pacchetto, rispetto alla radice del pacchetto. ExcludePath può essere usato (anziché gli altri due attributi) per selezionare i file da escludere da quelli selezionati dagli altri attributi SourcePath degli altri elementi file all'interno dello stesso pacchetto.

Ogni elemento File può essere usato per selezionare più file usando caratteri jolly. In generale, è possibile usare un singolo carattere jolly (*) in qualsiasi punto all'interno del percorso un numero qualsiasi di volte. Tuttavia, un singolo carattere jolly corrisponderà solo ai file all'interno di una cartella e non ad alcuna sottocartella. Ad esempio, C:\MyGame\*\* può essere usato in SourcePath per selezionare i file C:\MyGame\Audios\UI.mp3 e C:\MyGame\Videos\intro.mp4, ma non può selezionare C:\MyGame\Audios\Level1\warp.mp3. Il doppio carattere jolly (**) può essere usato anche al posto di nomi di file o cartelle per trovare qualsiasi corrispondenza ricorsiva (ma non può essere accanto a nomi parziali). Ad esempio, C:\MyGame\**\Level1\** può selezionare C:\MyGame\Audios\Level1\warp.mp3 e C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4. I caratteri jolly possono essere usati anche per modificare direttamente i nomi dei file come parte del processo di creazione del pacchetto se i caratteri jolly vengono usati in posizioni diverse tra l'origine e la destinazione. Ad esempio, avere C:\MyGame\Audios\* per SourcePath e Sound\copy_* per DestinationPath può selezionare C:\MyGame\Audios\UI.mp3 e visualizzarlo nel pacchetto come Sound\copy_UI.mp3. In generale, il numero di caratteri jolly singoli e caratteri jolly double deve essere lo stesso per SourcePath e DestinationPath di un singolo elemento File.

Esempio di layout avanzato per la creazione di pacchetti

Di seguito è riportato un esempio di layout di creazione di pacchetti più complesso:

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

Questo esempio è diverso dall'esempio semplice con l'aggiunta di elementi ResourcePackage e Facoltativi .

I pacchetti di risorse possono essere specificati con l'elemento ResourcePackage . All'interno di ResourcePackage, l'elemento Resources deve essere usato per specificare i qualificatori di risorsa del pacchetto di risorse. I qualificatori di risorse sono le risorse supportate dal pacchetto di risorse, qui è possibile notare che sono presenti due pacchetti di risorse definiti e ognuno contiene i file specifici in inglese e francese. Un pacchetto di risorse può avere più di un qualificatore, questa operazione può essere eseguita aggiungendo un altro elemento Resource all'interno di Resources. È necessario specificare anche una risorsa predefinita per la dimensione della risorsa se la dimensione esiste (dimensioni in lingua, scala, dxfl). In questo caso, è possibile notare che l'inglese è la lingua predefinita, vale a dire che per gli utenti che non hanno una lingua di sistema del set francese, eseguiranno il fallback per scaricare il pacchetto di risorse inglese e visualizzare in inglese.

I pacchetti facoltativi hanno nomi distinti della famiglia di pacchetti e devono essere definiti con gli elementi PackageFamily , specificando l'attributo Facoltativo come true. L'attributo RelatedSet viene usato per specificare se il pacchetto facoltativo si trova all'interno del set correlato (per impostazione predefinita è true), ovvero se il pacchetto facoltativo deve essere aggiornato con il pacchetto primario.

L'elemento PrebuiltPackage viene usato per aggiungere pacchetti che non sono definiti nel layout di creazione del pacchetto da includere o fare riferimento nei file bundle dell'app. In questo caso, viene incluso un altro pacchetto facoltativo DLC in modo che il file bundle dell'app principale possa farvi riferimento e far parte del set correlato.

Creare pacchetti di app con un layout di creazione di pacchetti e MakeAppx.exe

Dopo aver creato il layout di creazione dei pacchetti per l'app, puoi iniziare a usare MakeAppx.exe per compilare i pacchetti dell'app. Per compilare tutti i pacchetti definiti nel layout dei pacchetti, usare il comando :

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

Tuttavia, se si aggiorna l'app e alcuni pacchetti non contengono file modificati, è possibile compilare solo i pacchetti modificati. Usando l'esempio di layout di creazione di pacchetti semplice in questa pagina e creando il pacchetto di architettura x64, il comando sarà simile al seguente:

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

Il /id flag può essere usato per selezionare i pacchetti da compilare dal layout di creazione del pacchetto, corrispondente all'attributo ID nel layout. Viene /ip utilizzato per indicare dove si trova la versione precedente dei pacchetti. La versione precedente deve essere fornita perché il file bundle dell'app deve comunque fare riferimento alla versione precedente del pacchetto multimediale . Il /iv flag viene usato per incrementare automaticamente la versione dei pacchetti compilati (invece di modificare la versione in AppxManifest). In alternativa, le opzioni /pv e /bv possono essere usate per fornire direttamente una versione del pacchetto (per tutti i pacchetti da creare) e una versione bundle (rispettivamente per tutti i bundle da creare). Usando l'esempio di layout di creazione pacchetti avanzato in questa pagina, se si desidera compilare solo il bundle facoltativo Temi e il pacchetto dell'app Themes.main a cui fa riferimento, usare questo comando:

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

Il /bc flag viene usato per indicare che gli elementi figlio del bundle Temi devono essere compilati anche (in questo caso Themes.main verrà compilato). Il /nbp flag viene usato per indicare che l'elemento padre del bundle Themes non deve essere compilato. L'elemento padre di Themes, che è un bundle di app facoltativo, è il bundle principale dell'app: MyGame. In genere per un pacchetto facoltativo in un set correlato, il bundle dell'app principale deve essere compilato anche per consentire l'installazione del pacchetto facoltativo, poiché viene fatto riferimento anche al pacchetto facoltativo nel bundle dell'app primaria quando si trova in un set correlato (per garantire il controllo delle versioni tra il pacchetto primario e i pacchetti facoltativi). La relazione padre figlio tra i pacchetti è illustrata nel diagramma seguente:

Packaging Layout Diagram