Udostępnij przez


Tworzenie pakietu za pomocą układu opakowań

Wraz z wprowadzeniem pakietów zasobów deweloperzy mają teraz narzędzia do tworzenia większej liczby pakietów oprócz większej liczby typów pakietów. Ponieważ aplikacja staje się coraz większa i bardziej złożona, często składa się z większej liczby pakietów, a trudności z zarządzaniem tymi pakietami wzrosną (zwłaszcza jeśli tworzysz poza programem Visual Studio i używasz plików mapowania). Aby uprościć zarządzanie strukturą tworzenia pakietów aplikacji, możesz użyć układu pakietów obsługiwanego przez MakeAppx.exe.

Układ pakowania to pojedynczy dokument XML opisujący strukturę tworzenia pakietów aplikacji. Określa pakiety aplikacji (podstawowe i opcjonalne), pakiety w pakietach i pliki w pakietach. Pliki można wybierać z różnych folderów, dysków i lokalizacji sieciowych. Symbole wieloznaczne mogą służyć do wybierania lub wykluczania plików.

Po skonfigurowaniu układu pakowania dla aplikacji jest on używany z MakeAppx.exe do tworzenia wszystkich pakietów dla aplikacji w jednym wywołaniu wiersza polecenia. Układ pakowania można edytować, aby zmienić strukturę pakietu zgodnie z potrzebami wdrożenia.

Przykład prostego układu opakowania

Oto przykład prostego układu opakowania:

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

Przeanalizujmy ten przykład, aby zrozumieć, jak to działa.

PakietFamily

Ten układ pakowania utworzy pojedynczy prosty plik pakietu aplikacji z pakietem architektury x64 i pakietem zawartości "Media".

Element PackageFamily służy do definiowania pakietu aplikacji. Należy użyć atrybutu ManifestPath , aby podać plik AppxManifest dla pakietu. Plik AppxManifest powinien odpowiadać plikowi AppxManifest dla pakietu architektury pakietu. Należy również podać atrybut ID . Używa się go z MakeAppx.exe podczas tworzenia pakietu, aby można było stworzyć wyłącznie ten pakiet, jeśli chcesz. To będzie nazwa pliku pakietu wynikowego. Atrybut FlatBundle służy do opisywania typu pakietu, który chcesz utworzyć, prawda dla pakietu płaskiego (co można przeczytać więcej tutaj) i false dla pakietu klasycznego. Atrybut ResourceManager służy do określania, czy pakiety zasobów w tym pakiecie będą używać narzędzia MRT w celu uzyskania dostępu do plików. Jest to domyślnie prawda, ale od wersji 1803 systemu Windows 10 to nie jest jeszcze gotowe, więc ten atrybut musi być ustawiony na false.

Pakiet i pakiet zawartości

W elemencie PackageFamily zdefiniowane są pakiety, które pakiet aplikacji zawiera lub do których się odwołuje. W tym miejscu pakiet architektury (nazywany również pakietem głównym) jest definiowany za pomocą elementu Package , a pakiet zasobów jest definiowany za pomocą elementu AssetPackage . Pakiet architektury musi określać, dla której architektury jest przeznaczony pakiet : "x64", "x86", "arm" lub "neutral". Możesz również (opcjonalnie) bezpośrednio podać plik AppxManifest specjalnie dla tego pakietu, ponownie używając atrybutu ManifestPath . Jeśli nie podano pliku AppxManifest , zostanie on automatycznie wygenerowany z pliku AppxManifest dostarczonego dla elementu PackageFamily.

Domyślnie program AppxManifest zostanie wygenerowany dla każdego pakietu w pakiecie. W przypadku pakietu zasobów można również ustawić atrybut AllowExecution . Ustawienie tej opcji na false (wartość domyślna) pozwoli skrócić czas publikowania aplikacji, ponieważ pakiety, które nie muszą być uruchamiane, nie będą miały skanowania antywirusowego blokującego proces publikowania (więcej informacji na ten temat można znaleźć w sekcji Wprowadzenie do pakietów zasobów).

Pliki

W ramach każdej definicji pakietu można użyć elementu Plik , aby wybrać pliki, które mają zostać uwzględnione w tym pakiecie. Atrybut SourcePath to miejsce, w którym pliki są lokalnie. Możesz wybrać pliki z różnych folderów (podając ścieżki względne), różne dyski (udostępniając ścieżki bezwzględne), a nawet udziały sieciowe (podając coś takiego jak \\myshare\myapp\*). DestinationPath to miejsce, w którym pliki znajdą się w pakiecie, względem katalogu głównego pakietu. ExcludePath można użyć (zamiast pozostałych dwóch atrybutów), w ramach tego samego pakietu, aby wykluczyć pliki z tych wybranych przez atrybuty SourcePath innych elementów File.

Każdy element Plik może służyć do wybierania wielu plików przy użyciu symboli wieloznacznych. Ogólnie rzecz biorąc, pojedynczy symbol wieloznaczny (*) może być używany w dowolnym miejscu w ścieżce dowolną liczbę razy. Jednak pojedynczy symbol wieloznaczny będzie pasowany tylko do plików w folderze, a nie do podfolderów. Na przykład C:\MyGame\*\* można użyć w SourcePath do wyboru plików C:\MyGame\Audios\UI.mp3 i C:\MyGame\Videos\intro.mp4, ale nie może wybrać C:\MyGame\Audios\Level1\warp.mp3. Podwójne symbole wieloznaczne (**) mogą być również używane zamiast nazw folderów lub plików, aby dopasować wszystko w sposób rekursywny (ale nie mogą być obok częściowych nazw). Na przykład C:\MyGame\**\Level1\** może wybrać C:\MyGame\Audios\Level1\warp.mp3 i C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4. Symbole wieloznaczne mogą również służyć do bezpośredniego zmieniania nazw plików w ramach procesu pakowania, jeśli symbole wieloznaczne są używane w różnych miejscach między źródłem a miejscem docelowym. Na przykład, określenie C:\MyGame\Audios\* dla SourcePath i Sound\copy_* dla DestinationPath może spowodować wybór C:\MyGame\Audios\UI.mp3 i wyświetlenie go w pakiecie jako Sound\copy_UI.mp3. Ogólnie rzecz biorąc, liczba pojedynczych symboli wieloznacznych i podwójnych symboli wieloznacznych musi być taka sama dla SourcePath i DestinationPath elementu File.

Przykład zaawansowanego układu pakowania

Oto przykład bardziej skomplikowanego układu pakietów:

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

Ten przykład różni się od prostego przykładu z dodawaniem elementów ResourcePackage i Optional .

Pakiety zasobów można określić za pomocą elementu ResourcePackage . W ramach pakietu ResourcePackage element Resources musi służyć do określania kwalifikatorów zasobów pakietu zasobów. Kwalifikatory zasobów to zasoby obsługiwane przez pakiet zasobów. W tym miejscu widzimy, że zdefiniowano dwa pakiety zasobów i każdy z nich zawiera pliki specyficzne dla języka angielskiego i francuskiego. Pakiet zasobów może mieć więcej niż jeden kwalifikator. Można to zrobić, dodając inny element zasobu w obszarze Zasoby. Należy również określić domyślny zasób dla wymiaru zasobu, jeśli taki wymiar istnieje (np. język, skala, dxfl). W tym miejscu widzimy, że angielski jest językiem domyślnym, co oznacza, że dla użytkowników, którzy nie mają ustawionego języka systemowego na francuski, system przełączy się na pobieranie angielskiego pakietu zasobów i wyświetlanie treści w języku angielskim.

Opcjonalne pakiety mają własne odrębne nazwy rodzin pakietów i muszą być definiowane za pomocą elementów PackageFamily , określając atrybut opcjonalny jako true. Atrybut RelatedSet służy do określania, czy opcjonalny pakiet znajduje się w powiązanym zestawie (domyślnie jest to prawda) — czy opcjonalny pakiet powinien zostać zaktualizowany przy użyciu pakietu podstawowego.

Element PrebuiltPackage służy do dodawania pakietów, które nie są zdefiniowane w układzie pakowania, które mają być dołączone lub przywoływane w plikach pakietu aplikacji do skompilowania. W takim przypadku w tym miejscu jest dołączany inny opcjonalny pakiet DLC, dzięki czemu podstawowy plik pakietu aplikacji może się do niego odwoływać i mieć go częścią powiązanego zestawu.

Tworzenie pakietów aplikacji za pomocą układu pakietów i MakeAppx.exe

Po utworzeniu układu tworzenia pakietów dla aplikacji możesz rozpocząć tworzenie pakietów aplikacji przy użyciu MakeAppx.exe. Aby skompilować wszystkie pakiety zdefiniowane w układzie pakowania, użyj polecenia :

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

Jeśli jednak aktualizujesz aplikację, a niektóre pakiety nie zawierają żadnych zmienionych plików, możesz utworzyć tylko zmienione pakiety. Korzystając z prostego przykładu układu pakietów na tej stronie i budując pakiet architektury x64, tak wyglądałoby nasze polecenie:

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

Flaga /id może służyć do wybierania pakietów do skompilowania z układu opakowania odpowiadającego atrybutowi ID w układzie. Służy /ip do wskazywania, gdzie w tym przypadku znajduje się poprzednia wersja pakietów. Należy podać poprzednią wersję, ponieważ plik pakietu aplikacji nadal musi odwoływać się do poprzedniej wersji pakietu Media . Flaga /iv służy do automatycznego przyrostowania wersji tworzonych pakietów (zamiast zmiany wersji w programie AppxManifest). Alternatywnie przełączniki /pv i /bv mogą służyć do bezpośredniego udostępniania wersji pakietu (dla wszystkich pakietów do utworzenia) i wersji pakietu (dla wszystkich pakietów do utworzenia), odpowiednio. Korzystając z przykładowego zaawansowanego układu pakietów na tej stronie, jeśli chcesz utworzyć tylko opcjonalny pakiet Motywy i pakiet aplikacji Themes.main , do którego się odwołuje, użyj następującego polecenia:

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

Flaga /bc służy do oznaczania, że elementy podrzędne pakietu Motywy powinny być również skompilowane (w tym przypadku zostanie skompilowany plik Themes.main ). Flaga /nbp służy do oznaczania, że element nadrzędny pakietu Motywy nie powinien być kompilowany. Rodzic Themes, który jest opcjonalnym pakietem aplikacji i jest podstawowym pakietem aplikacji: MyGame. Zazwyczaj w przypadku opcjonalnego pakietu w powiązanym zestawie podstawowy pakiet aplikacji musi być również skompilowany, aby można było zainstalować opcjonalny pakiet, ponieważ opcjonalny pakiet jest również przywołyny w pakiecie podstawowej aplikacji, gdy znajduje się w powiązanym zestawie (w celu zagwarantowania przechowywania wersji między pakietami podstawowymi i opcjonalnymi). Relacja pomiędzy pakietem nadrzędnym a podrzędnym jest pokazana na poniższym diagramie:

Diagram układu pakietów