使用封裝配置的套件建立

隨著資產套件的推出,開發人員現在除了更多套件類型之外,還有可建置更多套件的工具。 當應用程式變得更大且更複雜的時,它通常會由更多套件組成,而且管理這些套件的難度將會增加(特別是如果您要在 Visual Studio 外部建置並使用對應檔案)。 若要簡化應用程式封裝結構的管理,您可以使用MakeAppx.exe支援的封裝配置。

封裝配置是描述應用程式封裝結構的單一 XML 檔。 它會指定應用程式套件組合(主要和選擇性)、套件組合中的套件,以及套件中的檔案。 您可以從不同的資料夾、磁碟驅動器和網路位置選取檔案。 通配符可用來選取或排除檔案。

設定應用程式的封裝配置之後,它會與 MakeAppx.exe 搭配使用,在單一命令行呼叫中建立應用程式的所有套件。 您可以編輯封裝配置來改變套件結構,以符合您的部署需求。

簡單封裝配置範例

以下是簡單封裝配置外觀的範例:

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

讓我們細分此範例以瞭解其運作方式。

PackageFamily

此封裝配置會建立具有 x64 架構套件和「媒體」資產套件的單一一般應用程式套件組合檔案。

PackageFamily 元素可用來定義應用程式套件組合。 您必須使用 ManifestPath 屬性來提供套件組合的 AppxManifest,AppxManifest 應對應至套件組合架構套件的 AppxManifest。 也必須提供ID 屬性。 這會在套件建立期間與 MakeAppx.exe 搭配使用,因此您可以視需要建立此套件,而這會是所產生套件的檔名。 FlatBundle 屬性可用來描述您想要建立的套件組合類型、一般套件組合的 true (您可以在這裡進一步閱讀),以及針對傳統套件組合的 false ResourceManager 屬性可用來指定此套件組合內的資源套件是否會使用 MRT 來存取檔案。 根據預設 ,這是 true,但從 Windows 10 版本 1803 開始,這尚未就緒,因此此屬性必須設定為 false

Package 和 AssetPackage

PackageFamily 中,會定義應用程式套件組合所包含的套件或參考。 在這裡,架構套件(也稱為主要套件)是使用 Package 元素來定義,而資產套件則是使用 AssetPackage 元素來定義。 架構套件必須指定套件針對哪一個架構,例如 「x64」、“x86”、“arm” 或 “neutral”。 您也可以再次使用ManifestPath屬性,直接為此套件提供AppxManifest如果未提供 AppxManifest,系統就會從 PackageFamily 提供的 AppxManifest 自動產生一個 AppxManifest

根據預設 ,AppxManifest 將會針對套件組合內的每個套件產生。 針對資產套件,您也可以設定 AllowExecution 屬性。 將此設定為 false (預設值),將有助於減少應用程式的發佈時間,因為不需要執行的套件不會封鎖其病毒掃描封鎖發佈程式(您可以在資產套件簡介中深入瞭解這一點)。

Files

在每個套件定義中,您可以使用 File 元素來選取要包含在此套件中的檔案。 SourcePath 屬性是檔案在本機的位置。 您可以從不同的資料夾選取檔案(藉由提供相對路徑)、不同的磁碟驅動器(藉由提供絕對路徑),或甚至網路共用(藉由提供類似 的內容 \\myshare\myapp\*)。 DestinationPath 是檔案最終會在套件內,相對於套件根目錄的位置。 ExcludePath 可以使用 (而不是其他兩個屬性)來選取要從相同封裝內其他 File 元素 SourcePath 屬性所選取的檔案中排除的檔案。

每個 File 元素都可以用來使用通配符來選取多個檔案。 一般而言,單一通配符 (*) 可以在路徑內的任何位置使用任意次數。 不過,單一通配符只會比對資料夾內的檔案,而不是任何子資料夾。 例如,C:\MyGame\*\*可以在SourcePath中使用 來選取檔案C:\MyGame\Audios\UI.mp3C:\MyGame\Videos\intro.mp4,但無法選取 C:\MyGame\Audios\Level1\warp.mp3。 雙通配符 (**) 也可用來取代資料夾或檔名,以遞歸方式比對任何專案(但不能在部分名稱旁邊)。 例如,C:\MyGame\**\Level1\**可以選擇 C:\MyGame\Audios\Level1\warp.mp3 與 。 C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4 如果通配符用於來源和目的地之間的不同位置,通配符也可以用來直接變更檔名作為封裝程式的一部分。 例如,針對 C:\MyGame\Audios\* SourcePath和 Sound\copy_*DestinationPath,可以選取C:\MyGame\Audios\UI.mp3並讓它出現在封裝中為 。Sound\copy_UI.mp3 一般而言,單一通配符和雙通配符的數目對於單一 File 元素的 SourcePath 和 DestinationPath 必須相同。

進階封裝配置範例

以下是更複雜的封裝配置範例:

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

此範例與新增 ResourcePackageOptional 元素的簡單範例不同。

您可以使用 ResourcePackage 元素來指定資源套件。 在 ResourcePackage 內,Resources 元素必須用來指定資源套件的資源限定符。 資源限定符是資源套件所支援的資源,在這裡,我們可以看到已定義兩個資源套件,且每個資源套件都包含英文和法文特定檔案。 資源套件可以有多個限定符,這可以藉由在 Resources新增另一個 Resource 元素來完成。 如果維度存在,也必須指定資源維度的默認資源(維度為語言、小數位數、dxfl)。 在這裡,我們可以看到英文是默認語言,這表示對於沒有法文組系統語言的用戶,他們會後援下載英文資源套件,並以英文顯示。

選擇性套件各自有自己的不同套件系列名稱,而且必須使用 PackageFamily 元素定義,同時指定 Optional 屬性為 true RelatedSet 屬性是用來指定選擇性套件是否在相關集合內(預設為 true) – 是否應該使用主要套件更新選用套件。

PrebuiltPackage 元素可用來新增未在要建置之應用程式套件組合檔案中包含或參考之封裝配置中未定義的套件。 在此情況下,這裡會包含另一個 DLC 選擇性套件,讓主要應用程式套件組合檔案可以參考它,並讓它成為相關集合的一部分。

使用封裝配置和MakeAppx.exe建置應用程式套件

當您擁有應用程式的封裝配置之後,您就可以開始使用MakeAppx.exe來建置應用程式的套件。 若要建置封裝設定中定義的所有套件,請使用 命令:

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

但是,如果您要更新應用程式,而某些套件不包含任何已變更的檔案,則只能建置已變更的套件。 使用此頁面上的簡單封裝版面配置範例和建置 x64 架構套件,這就是命令的外觀:

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

/id旗標可用來從封裝配置中選取要建置的封裝,對應至配置中的ID屬性。 /ip用來指出此案例中舊版套件的位置。 必須提供舊版,因為應用程式套件組合檔案仍然需要參考舊版的 媒體 套件。 旗/iv標是用來自動遞增所建置套件的版本(而不是變更 AppxManifest 中的版本)。 或者,參數 /pv/bv 可用來直接提供套件版本(針對要建立的所有套件)和套件組合版本(針對要建立的所有套件組合)。分別提供套件版本。 如果您想要只建置 [主題] 選用套件組合和它所參考的 Themes.main 應用程式套件,請使用這個命令,在此頁面上使用進階封裝配置範例:

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

/bc標用來表示也應該建置主題套件組合的子系 (在此案例中為 Themes.main 將會建置)。 旗/nbp標用來表示不應該建置主題套件組合的父系。 主題父系是選用的應用程式套件組合,是主要應用程式套件組合:MyGame。 通常對於相關集合中的選擇性套件,主要應用程式套件組合也必須針對可安裝的選用套件建置,因為當選用套件位於相關集合時,也會在主要應用程式套件組合中參考該套件組合(以確保主要套件與選擇性套件之間的版本設定)。 下圖說明封裝之間的父子關聯性:

Packaging Layout Diagram