패키징 레이아웃으로 패키지 만들기Package creation with the packaging layout

자산 패키지의 도입으로 개발자는 이제 도구를 더 많은 패키지 유형뿐만 아닌 더 많은 패키지를 빌드하는 도구를 갖추게 되었습니다.With the introduction of asset packages, developers now have the tools to build more packages in addition to more package types. 앱의 크기가 커지고 더 복잡해짐에 따라 종종 더 많은 패키지로 구성되며 이러한 패키지 관리의 어려움이 증가하고 있습니다(특히 Visual Studio 외부에서 빌드하고 매핑 파일을 사용하는 경우).As an app gets larger and more complex, it will often be comprised of more packages, and the difficulty of managing these packages will increase (especially if you are building outside of Visual Studio and using mapping files). 앱의 패키징 구조 관리를 간소화하기 위해 MakeAppx.exe에서 지원하는 패키징 레이아웃을 사용할 수 있습니다.To simplify the management of an app’s packaging structure, you can use the packaging layout supported by MakeAppx.exe.

패키징 레이아웃은 앱 패키징 구조를 설명하는 단일 XML 문서입니다.The packaging layout is a single XML document that describes packaging structure of the app. 앱(기본 및 선택)의 번들, 번들의 패키지, 패키지의 파일을 지정합니다.It specifies the bundles of an app (primary and optional), the packages in the bundles, and the files in the packages. 다른 폴더, 드라이브, 네트워크 위치에서 파일을 선택할 수 있습니다.Files can be selected from different folders, drives, and network locations. 파일을 선택하거나 제외하는 데 와일드카드를 사용할 수 있습니다.Wildcards can be used to select or exclude files.

앱에 대한 레이아웃을 패키징하면 MakeAppx.exe와 단일 명령줄 호출에서 앱에 대한 모든 패키지를 만드는 데 사용됩니다.After the packaging layout for an app has been set up, it's used with MakeAppx.exe to create all of the packages for an app in a single command line call. 패키징 레이아웃은 배포 요구에 맞게 패키지 구조를 변경할 수 있도록 편집할 수 있습니다.The packaging layout can be edited to alter the package structure to fit your deployment needs.

단순한 패키징 레이아웃 예Simple packaging layout example

단순한 패키징 레이아웃의 모습의 예는 다음과 같습니다.Here's an example of what a simple packaging layout looks like:

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

이 예를 살펴 작동 방식을 파악해 보겠습니다.Let's break this example down to understand how it works.

PackageFamilyPackageFamily

이 패키징 레이아웃은 x64 아키텍처 패키지와 "미디어" 자산 패키지를 포함 하는 단일 플랫 앱 번들 파일을 만듭니다.This packaging layout will create a single flat app bundle file with an x64 architecture package and a “Media” asset package.

PackageFamily 요소는 앱 번들을 정의하는 데 사용됩니다.The PackageFamily element is used to define an app bundle. 번들에 대한 AppxManifest를 제공하기 위해 ManifestPath 특성을 사용해야 하며 AppxManifest는 번들의 아키텍처 패키지에 대한 AppxManifest애 해당해야 합니다.You must use the ManifestPath attribute to provide an AppxManifest for the bundle, the AppxManifest should correspond to the AppxManifest for the architecture package of the bundle. ID 특성도 제공해야 합니다.The ID attribute must also be provided. 이는 패키지를 생성하는 동안 MakeAppx.exe에 사용되기 때문에 원하는 경우 이 패키지만 만들 수 있으며 결과 패키지의 파일 이름이 됩니다.This is used with MakeAppx.exe during package creation so that you can create just this package if you want to, and this will be the file name of the resulting package. FlatBundle 특성은 만들려는 유형의 번들을 설명하는 데 사용되면 플랫 번들의 경우 true(여기에서 자세한 내용을 알아볼 수 있음), 클래식 번들의 경우 false입니다.The FlatBundle attribute is used to describe what type of bundle you want to create, true for a flat bundle (which you can read more about here), and false for a classic bundle. ResourceManager 특성은 이 번들 내 리소스 패키지가 파일에 액세스하기 위해 MRT를 사용할지 여부를 지정하는 데 사용됩니다.The ResourceManager attribute is used to specify if the resource packages within this bundle will use MRT in order to access the files. 기본적으로 true지만 Windows 10 버전을 1803에서는 아직 준비가 되지 않았으므로 이 특성은 false로 설정해야 합니다.This is by default true, but as of Windows 10, version 1803, this is not yet ready, so this attribute must be set to false.

패키지 및 AssetPackagePackage and AssetPackage

PackageFamily 내에서 앱 번들이 포함 또는 참조하는 패키지가 정의됩니다.Within the PackageFamily, the packages that the app bundle contains or references are defined. 여기서 아키텍처 패키지(주 패키지라고도 함)는 패키지 요소로 정의되며 자산 패키지는 AssetPackage 요소로 정의됩니다.Here, the architecture package (also called the main package) is defined with the Package element, and the asset package is defined with the AssetPackage element. 아키텍처 패키지는 패키지가 "x64", "x86", "arm" 또는 "중립" 중에 어떤 아키텍처용인지 지정해야 합니다.The architecture package must specify which architecture the package is for, either “x64”, “x86”, “arm”, or “neutral”. (선택 사항)ManifestPath 특성을 다시 사용하여 특별히 이 패키지에 대한 AppxManifest를 직접 제공할 수 있습니다.You can also (optionally) directly provide an AppxManifest specifically for this package by using the ManifestPath attribute again. AppxManifest를 제공하지 않으면 PackageFamily에 대해 제공되는 AppxManifest에서 자동으로 생성됩니다.If an AppxManifest is not provided, one will be automatically generated from the AppxManifest provided for the PackageFamily.

기본적으로 AppxManifest는 번들 내 모든 패키지에 대해 생성됩니다.By default and AppxManifest will be generated for every package within the bundle. 자산 패키지의 경우 AllowExecution 특성을 설정할 수도 있습니다.For the asset package, you can also set the AllowExecution attribute. 이를 false로 설정하면 실행할 필요가 없는 패키지에 게시 프로세스를 차단하는 바이러스 검사가 없으므로 앱 게시 시간을 줄일 수 있습니다(자산 패키지 소개에서 이에 대해 자세히 알아볼 수 있습니다).Setting this to false (the default), will help decrease the publishing time for your app since packages that don’t need to execute won’t have their virus scan block the publishing process (you can learn more about this at Introduction to asset packages).

파일Files

각 패키지 정의 내에서 File 요소를 사용하여 이 패키지에 포함되는 파일을 선택합니다.Within each package definition, you can use the File element to select files to be included in this package. SourcePath 특성에 파일이 로컬로 위치합니다.The SourcePath attribute is where the files are locally. 다른 폴더(상대 경로를 제공하여), 다른 드라이브(절대 경로를 제공하여), 또는 네트워크 공유(\\myshare\myapp\* 등을 제공하여)에서 파일을 선택할 수 있습니다.You can select files from different folders (by providing relative paths), different drives (by providing absolute paths), or even network shares (by providing something like \\myshare\myapp\*). DestinationPath는 패키지 루트를 기준으로 패키지 내 파일이 끝나는 위치입니다.The DestinationPath is where the files will end up within the package, relative to the package root. 다른 두 특성 대신 ExcludePath를 사용하여 같은 패키지 내 다른 File 요소의 SourcePath 특성에 의해 선택된 파일에서 제외할 파일을 선택할 수 있습니다.ExcludePath can be used (instead of the other two attributes) to select files to be excluded from the ones selected by other File elements’ SourcePath attributes within the same package.

File 요소는 와일드카드를 사용하여 여러 파일을 선택하는 데 사용할 수 있습니다.Each File element can be used to select multiple files by using wildcards. 일반적으로 단일 와일드카드(*)는 몇 번이든 경로 내 어디에서나 사용할 수 있습니다.In general, single wildcard (*) can be used anywhere within the path any number of times. 그러나 단일 와일드카드는 폴더 내에 있는 파일과만 일치하며 모든 하위 폴더에 있는 파일과는 일치하지 않습니다.However, a single wildcard will only match the files within a folder and not any subfolders. 예를 들어, C:\MyGame\*\*SourcePath에서 사용하여 C:\MyGame\Audios\UI.mp3C:\MyGame\Videos\intro.mp4 파일을 선택할 수 있지만 C:\MyGame\Audios\Level1\warp.mp3를 선택할 수 없습니다.For example, C:\MyGame\*\* can be used in the SourcePath to select the files C:\MyGame\Audios\UI.mp3 and C:\MyGame\Videos\intro.mp4, but it cannot select C:\MyGame\Audios\Level1\warp.mp3. 더블 와일드카드(**)는 반복적으로 어느 것이든 일치하기 위해 폴더 또는 파일 위치에서 사용할 수 있습니다(하지만 부분 이름 옆에 있을 수는 없음).The double wildcard (**) can also be used in place of folder or file names to match anything recursively (but it cannot be next to partial names). 예를 들어, C:\MyGame\**\Level1\**C:\MyGame\Audios\Level1\warp.mp3C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4를 선택할 수 있습니다.For example, C:\MyGame\**\Level1\** can select C:\MyGame\Audios\Level1\warp.mp3 and C:\MyGame\Videos\Bonus\Level1\DLC1\intro.mp4. 와일드카드가 원본과 대상 간에 여러 장소에서 사용되는 경우 패키징 과정의 일환으로 파일 이름을 직접 변경하기 위해 와일드카드를 사용할 수도 있습니다.Wildcards can also be used to directly change file names as part of the packaging process if the wildcards are used in different places between the source and destination. 예를 들어, SourcePathC:\MyGame\Audios\*를 가지고 DestinationPath에 대해 Sound\copy_*를 가지면 C:\MyGame\Audios\UI.mp3를 선택하고 패키지에 Sound\copy_UI.mp3로 표시할 수 있습니다.For example, having C:\MyGame\Audios\* for SourcePath and Sound\copy_* for DestinationPath can select C:\MyGame\Audios\UI.mp3 and have it appear in the package as Sound\copy_UI.mp3. 일반적으로 단일 와일드카드 및 이중 와일드카드의 수는 단일 File 요소의 SourcePathDestinationPath와 동일해야 합니다.In general, the number of single wildcards and double wildcards must be the same for the SourcePath and DestinationPath of a single File element.

고급 패키징 레이아웃 예Advanced packaging layout example

좀 더 복잡 한 패키징 레이아웃의 예는 다음과 같습니다.Here's an example of a more complicated packaging layout:

<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 요소가 추가된 단순한 예와 다릅니다.This example differs from the simple example with the addition of ResourcePackage and Optional elements.

리소스 패키지는 ResourcePackage 요소로 지정할 수 있습니다.Resource packages can be specified with the ResourcePackage element. ResourcePackage 내에서 Resources 요소는 리소스 팩의 리소스 한정자를 지정하는 데 사용해야 합니다.Within the ResourcePackage, the Resources element must be used to specify the resource qualifiers of the resource pack. 리소스 한정자는 리소스 팩에서 지원되는 리소스입니다. 여기에서 정의된 리소스 팩이 두 개 있으며 각각 영어 및 프랑스어와 관련된 파일이 포함된다는 것을 알 수 있습니다.The resource qualifiers are the resources that are supported by the resource pack, here, we can see that there are two resource packs defined and they each contain the English and French specific files. 리소스 팩은 하나 이상의 한정자를 가질 수 있으며 Resources 내 다른 Resource 요소를 추가하여 이 작업을 수행할 수 있습니다.A resource pack can have more than one qualifier, this can be done by adding another Resource element within Resources. 리소스 차원에 대한 기본 리소스는 차원이 있는지 지정해야 합니다(언어, 크기, dxfl 등의 차원).A default resource for the resource dimension must also be specified if the dimension exists (dimensions being language, scale, dxfl). 여기에서 영어가 기본 언어임을 확인할 수 있으며 이는 프랑스어 시스템 언어가 설정되지 않은 사용자에 대해 영어 리소스 팩을 다운로드하여 영어로 표시할 것임을 의미합니다.Here, we can see that English is the default language, meaning that for users that does not have a system language of French set, they will fallback to downloading the English resource pack and display in English.

선택적 패키지 각각에는 고유한 패키지 패밀리 이름이 있으며 PackageFamily 요소로 정의해야 합니다. 선택적 특성은 true로 지정해야 합니다.Optional packages each have their own distinct package family names and must be defined with PackageFamily elements, while specifying the Optional attribute to be true. RelatedSet 특성은 선택적 패키지가 관련 집합 내에 있는지 여부, 즉 선택적 패키지가 주 패키지 내에서 업데이트되어야 하는지 여부를 지정하는 데 사용됩니다(기본적으로 true입니다).The RelatedSet attribute is used to specify whether the optional package is within the related set (by default this is true) – whether the optional package should be updated with the primary package.

PrebuiltPackage 요소는 패키징 레이아웃에 정의 되지 않은 패키지를 추가 하는 데 사용 됩니다 .이 패키지는 빌드할 앱 번들 파일에서 포함 하거나 참조 하도록 패키지 레이아웃에 정의 되어 있지 않습니다.The PrebuiltPackage element is used to add packages that are not defined in the packaging layout to be included or referenced in the app bundle file(s) to be built. 이 경우 기본 앱 번들 파일이이를 참조 하 여 관련 집합의 일부가 되도록 다른 DLC 선택적 패키지가 여기에 포함 됩니다.In this case, another DLC optional package is being included here so that the primary app bundle file can reference it and have it be part of the related set.

패키징 레이아웃과 MakeAppx.exe로 앱 패키지 빌드Build app packages with a packaging layout and MakeAppx.exe

앱에 대한 패키징 레이아웃이 있으면 MakeAppx.exe를 사용하여 앱 패키지 빌드를 시작할 수 있습니다.Once you have the packaging layout for your app, you can start using MakeAppx.exe to build the packages of your app. 패키징 레이아웃에 정의된 모든 패키지를 빌드하려면 다음 명령을 사용합니다.To build all of the packages defined in the packaging layout, use the command:

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

그러나 앱을 업데이트하고 일부 패키지에 변경된 파일이 모두 포함되지 않는 경우 변경된 패키지만 빌드할 수 있습니다.But, if you are updating your app and some packages don't contain any changed files, you can build only the packages that have changed. 이 페이지에서 단순한 패키징 레이아웃 예를 사용하여 x64 아키텍처 패키지를 빌드하면 명령은 다음과 같은 모습입니다.Using the simple packaging layout example on this page and building the x64 architecture package, this is what our command would look like:

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

/id 플래그를 사용하여 레이아웃의 ID 특성에 해당하는 패키징 레이아웃에서 빌드할 패키지를 선택할 수 있습니다.The /id flag can be used to select the packages to be built from the packaging layout, corresponding to the ID attribute in the layout. 이 경우 /ip는 패키지의 이전 버전의 위치를 나타내는 데 사용됩니다.The /ip is used to indicate where the previous version of the packages are in this case. 앱 번들 파일은 여전히 이전 버전의 미디어 패키지를 참조 해야 하기 때문에 이전 버전을 제공 해야 합니다.The previous version must be provided because the app bundle file still needs to reference the previous version of the Media package. /iv 플래그는 빌드되는 패키지의 버전을 자동으로 증분하는 데 사용됩니다(AppxManifest에서 버전을 변경하는 대신).The /iv flag is used to automatically increment the version of the packages being built (instead of changing the version in the AppxManifest). 또한 /pv/bv 스위치는 직접 패키지 버전(만들 모든 패키지에 대한)과 번들 버전(만들 모든 번들에 대한)을 제공하는 데 사용할 수 있습니다.Alternatively, the switches /pv and /bv can be used to directly provide a package version (for all packages to be created) and a bundle version (for all bundles to be created), respectively. 고급 패키징 레이아웃 예를 사용하여 테마 선택적 번들 및 이를 참조하는 Themes.main만 빌드하려는 경우 이 명령을 사용해야 합니다.Using the advanced packaging layout example on this page, if you want to only build the Themes optional bundle and the Themes.main app package that it references, you would use this command:

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

/bc 플래그는 테마 번들의 자식도 빌드해야 함을 나타내는 데 사용됩니다(이 경우 Themes.main이 빌드됩니다).The /bc flag is used to denote that the children of the Themes bundle should also be built (in this case Themes.main will be built). /nbp 플래그는 테마 번들의 부모를 빌드해서는 안 됨을 나타내는 데 사용됩니다.The /nbp flag is used to denote that the parent of the Themes bundle should not be built. 선택적 앱 번들인 테마의 부모는 기본 앱 번들 MyGame입니다.The parent of Themes, which is an optional app bundle, is the primary app bundle: MyGame. 선택적 패키지는 관련 집합에 있을 때 (주 패키지 및 선택적 패키지 간에 버전을 보장하기 위해) 기본 앱 번들에서도 참조되기 때문에 일반적으로 관련 집합의 선택적 패키지에 대해 선택적 패키지를 설치하기 위해 기본 앱 번들도 구축해야 합니다.Usually for an optional package in a related set, the primary app bundle must also be built for the optional package to be installable, since the optional package is also referenced in the primary app bundle when it is in a related set (to guarantee versioning between the primary and the optional packages). 다음 다이어그램에서는 패키지 간 부모 자식 관계를 보여 줍니다.The parent child relationship between packages is illustrated in the following diagram:

패키지 레이아웃 다이어그램