Every MSIX package is one of four package types:
- Main
- Framework
- Resource
- Optional
MSIX also supports Bundle packages. Bundles are somewhat different from those four package types: a Bundle is a container for one or more MSIX packages. Windows APIs nevertheless expose Bundle alongside the other package types when identifying packages.
Each package type has its own behaviors, nuances, and rationale worthy of a dedicated discussion. We’ll take a brief whirlwind tour of MSIX package types here and explore them in greater detail in future blog posts.
What does PackageType imply?
What does PackageType actually mean?
MSIX packages have various properties and behaviors. A package type defines a predefined combination of properties and behaviors. Some are inherent to the package type, while others merely have defaults determined by the package type and can be overridden in AppxManifest.xml.
<packagedependency> is an example of a behavior constrained by package type. Main packages can declare static package dependencies, whereas Framework and Resource packages can’t.
Whether package content may execute is an example of a behavior whose default is based on package type but can be overridden via <uap6:allowexecution>. Main, Framework, and Optional packages permit execution by default, while Resource packages do not, unless the default is explicitly overridden.
For example, a Resource package can override its default behavior by declaring <uap6:AllowExecution>true</uap6:AllowExecution> in its AppxManifest.xml.
Main package
A Main package represents the primary package for an application.
Main packages are the package type developers and users encounter most frequently. A Main package can declare applications in AppxManifest.xml via <application>, as well as <capabilities>, <dependencies>, WinRT out-of-process (OOP) servers and more.
Windows Terminal (Microsoft.WindowsTerminal_8wekyb3d8bbwe), winappCLI (winapp_8wekyb3d8bbwe) and many more are Main packages.
There is no explicit “I am a Main package” marker in AppxManifest.xml. A package is a Main package when it does not declare itself to be another package type.
Framework package
Framework packages provide shared libraries, components, resources, or other runtime content for use by other packages or processes.
Conceptually, the relationship is closer to a shared component and the applications that consume it. A Framework package has package identity, but it does not represent an independently activated application of its own. Instead, its content can be incorporated into the package graph of processes that use it.
Framework packages also have special servicing semantics: multiple versions may remain installed side-by-side while applications transition from an older version to a newer one.
The Windows App SDK Framework package (Microsoft.WindowsAppRuntime.2_8wekyb3d8bbwe) is one example. It provides WinUI 3, PackageDeploymentManager and other APIs.
A package is a Framework package because it declares <framework>true</framework> in its AppxManifest.xml.
Resource package
Resource packages provide resources associated with another package.
Resource packages separate language-, scale-, and other resource-specific content from a Main or Optional package so Windows can install only the resources applicable to a device or user.
Images for varying display scales, localization data (text, images, etc.), and other resources are typically provided via Resource packages. Resource packages can include executable code, including DLLs and EXEs, if they declare <uap6:AllowExecution>true</uap6:AllowExecution>; spelling and grammar checkers are common examples of why a Resource package might need to allow execution.
A package is a Resource package because it declares <resourcepackage>true</resourcepackage> in its AppxManifest.xml.
Optional package
Optional packages contain additional content or code intended to be integrated with a specific Main package.
Unlike a Framework package, which can be used by multiple package families (and unpackaged processes1), an Optional package is associated with a particular Main package.
The concept behind Optional packages is to enable developers to break a large package into a required Main package and one or more optional packages. For example, a packaged game could have the game itself and additional optional elements. This could all be shipped in one Main package, but doing so can be undesirable when the additional content is large and many users don’t need it. Instead, the application could be split into multiple packages:
- Game.msix – a Main package containing the core
game.exeandgame.dat - Maps.msix – an Optional package containing additional maps
- MapEditor.msix – an Optional package containing
mapeditor.exe2 - HighRes.msix – an Optional package containing alternative high-resolution graphics
Downloadable Content (DLC) for games is one example of why developers might choose to use Optional packages. Many scenarios originally envisioned for Optional packages may now be better addressed by newer mechanisms. For example, plug-in architectures are often better served using Dynamic Dependencies together with AppExtensions or PackageExtensions.
A package is an Optional package because it declares a <uap3:mainpackagedependency>.
Bundle package
A Bundle package is somewhat different from other types of packages.
An MSIX bundle (*.msixbundle) is a container for one or more MSIX packages (*.msix).
For example, consider an application compiled for x86, x64, and Arm64, with separate MSIX packages for each architecture: Contoso.PointOfSale-x86.msix, Contoso.PointOfSale-x64.msix, and Contoso.PointOfSale-arm64.msix. The application might also support dozens of languages, display scales, and other resource qualifiers split across multiple Resource packages.
Managing all of those packages individually would be cumbersome. A Bundle such as Contoso.PointOfSale.msixbundle can contain them in a single distribution artifact.
A Bundle provides a convenient distribution unit while allowing deployment to select only the architecture and resource packages applicable to the target system.
All packages in a bundle belong to the same Package Family.
Bundle package identity uses a ResourceId of tilde (~ aka U+007E).
Synopsis
| Type | Primary purpose | Manifest / identity indicator |
|---|---|---|
| Main | Primary package for an application | No other package-type declaration |
| Framework | Shared runtime content | <Framework>true</Framework> |
| Resource | Applicability-specific resources | <ResourcePackage>true</ResourcePackage> |
| Optional | Additional content associated with a Main package | <uap3:MainPackageDependency> |
| Bundle | Distribution container for MSIX packages | Bundle manifest; ResourceId="~" identity |
Detect PackageType
The Windows.ApplicationModel.Package class exposes properties for identifying a package type:
| PackageType | Windows.ApplicationModel.Package property |
|---|---|
| Main | !package.IsFramework && !package.IsResourcePackage && !package.IsOptional && !package.IsBundle |
| Framework | package.IsFramework |
| Resource | package.IsResourcePackage |
| Optional | package.IsOptional |
| Bundle | package.IsBundle |
Detect via PowerShell
Get-AppxPackage reports several package-type properties:
Get-AppxPackage micro*win*app*run*2
...
PackageFullName : Microsoft.WindowsAppRuntime.2_2.4.0.0_x64__8wekyb3d8bbwe
...
IsFramework : True
...
IsResourcePackage : False
IsBundle : False
Get-AppxPackage does not expose an IsOptional property analogous to IsFramework, IsResourcePackage, and IsBundle.
By default, Get-AppxPackage only enumerates Main and Framework packages. Use the -PackageTypeIdentifier parameter to filter by more (or fewer) types of packages. Specify -PackageTypeIdentifier Main,Framework,Resource,Optional,Bundle to match all package types. For example:
$(Get-AppxPackage Contoso.PointOfSale -PackageTypeIdentifier Main,Framework,Resource,Optional,Bundle).PackageFullName
...
Contoso.PointOfSale_1.2.3.4_arm64__8wekyb3d8bbwe
Contoso.PointOfSale_1.2.3.4_neutral_language-tlh_8wekyb3d8bbwe
Contoso.PointOfSale_1.2.3.4_neutral_language-qya_8wekyb3d8bbwe
Contoso.PointOfSale_1.2.3.4_neutral_scale-100_8wekyb3d8bbwe
Contoso.PointOfSale_1.2.3.4_neutral_scale-150_8wekyb3d8bbwe
What’s next?
Package type affects far more than a label. It influences package relationships, dependency resolution, execution, servicing, deployment, and runtime behavior.
This was the whirlwind tour. In future Inside MSIX posts we’ll explore the individual package types, their behaviors, and some of their less obvious consequences in considerably greater detail.
1 Framework packages can also be used by unpackaged processes via Dynamic Dependencies.
2 Optional packages containing executable code have additional requirements, including membership in a related set.
This post seems to be missing words. One example is:
“Main packages are the package type developers and users encounter most frequently. A Main package can declare applications in AppxManifest.xml via , as well as , , WinRT out-of-process (OOP) servers and more.”
Was this a case of being used in such a way that they are being seen as delimiters for HTML tags and the tag is being stripped out?
Wow! WordPress threw a spanner reformatting (and altering content!) for XML inside hyperlinks, among other formatting hijinks.
Fixed now. Thanks for the heads up!