Pack URIs in Windows Presentation Foundation

To identify application data files (see Windows Presentation Foundation Application Data Files), WPF utilizes a well-known and extensible uniform resource identifier (URI)-based mechanism that is known as the Pack URI Scheme. The extensibility of the Pack URI Scheme allows WPF to support a single and consistent method for identifying several types of application data files that can exist in a variety of locations.

This topic contains the following sections.

  • The Pack URI Scheme
  • Resource File Pack URIs - Local Assembly
  • Resource File Pack URIs - Referenced Assembly
  • Content File Pack URIs
  • Site of Origin File Pack URIs
  • Absolute vs Relative Pack URIs
  • Pack URI Resolution
  • Programming with Pack URIs
  • Using Pack URIs in Markup
  • Using Pack URIs in Code
  • Related Topics

The Pack URI Scheme

The Open Packaging Conventions (OPC) specification describes a model for organizing and identifying content. The core of this model revolves around two logical entities: packages and parts. A package is a container for one or more content parts, as illustrated by the following figure.

Package and Parts diagram

To be able to identify these parts, the OPC leverages the extensibility of RFC 2396 to define the Pack URI Scheme. The scheme that is specified by a URI is defined by its prefix; http, ftp, and file are well known examples. The Pack URI Scheme uses pack as its scheme, and contains two components: authority and path. The authority specifies the type of package that a part is contained by, while the path specifies the location of a part within a package. This concept is illustrated by the following figure:

A URI that conforms to the Pack URI Scheme is known as a "pack URI", and has the following format:

pack://<authority><path>

The concept of packages and parts is analogous to applications and application data files, where an application (package) can include one or more application data files (parts), including:

  • Resource files that are compiled into the local assembly.

  • Resource files that are compiled into a referenced assembly.

  • Resource files that are compiled into a referencing assembly.

  • Content files.

  • Site of origin files.

To access these four types of application data files, WPF supports two authorities, application:/// and siteoforigin:///. The application:/// authority is used to identify application data files that are known at compile time, including both resource files and content files. The siteoforigin:/// authority is used to identify site of origin files.

NoteNote:

The authority component of a pack URI is an embedded URI that points to a package and must conform to RFC 2396. Additionally, the "/" character must be replaced with the "," character, and reserved characters like "%" and "?" need to be escaped. See the OPC for details.

The scope of each authority is shown in the following figure:

Pack URI diagram

The following topics explain how to construct pack URIs using these two authorities in conjunction with paths to identify resource files, content files, and site of origin files.

Resource File Pack URIs - Local Assembly

The pack URI for a resource file that is compiled into the local assembly uses the following authority and path:

  • Authority: application:///.

  • Path: The name of the resource file, including its path relative to the root of the local assembly project folder.

The following example shows the pack URI for a XAML resource file that is located in the root of the local assembly's project folder:

pack://application:,,,/ResourceFile.xaml

The following example shows the pack URI for a XAML resource file that is located in a subfolder of the local assembly's project folder:

pack://application:,,,/Subfolder/ResourceFile.xaml

Resource File Pack URIs - Referenced Assembly

The pack URI for a resource file that is compiled into a referenced assembly uses the following authority and path:

  • Authority: application:///.

  • Path: The path for a resource file that is compiled into a referenced assembly conforms to the following format:

    AssemblyShortName[;Version][;PublicKey];component*/Path*

    • AssemblyShortName is the short name for the referenced assembly.

    • ;Version [optional] refers to the version of the referenced assembly that contains the resource file. This is used when two or more referenced assemblies with the same short name are loaded.

    • ;PublicKey [optional] refers to the public key that was used to sign the referenced assembly. This is used when two or more referenced assemblies with the same short name are loaded.

    • ;component specifies that the assembly being referred to is referenced from the local assembly.

    • /Path is the name of the resource file, including its path relative to the root of the referenced assembly's project folder.

The following example shows the pack URI for a XAML resource file that is located in the root of the referenced assembly's project folder:

pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml

The following example shows the pack URI for a XAML resource file that is located in a subfolder of the referenced assembly's project folder:

pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

The following example shows the pack URI for a XAML resource file that is located in the root folder of a referenced, version-specific assembly's project folder:

pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml

Content File Pack URIs

The pack URI for a content file uses the following authority and path:

  • Authority: application:///.

  • Path: The name of the content file, including its path relative to the file system location of the application's main executable assembly.

The following example shows the pack URI for a XAML content file, located in the same folder as the executable assembly:

pack://application:,,,/ContentFile.xaml

The following example shows the pack URI for a XAML content file, located in a subfolder that is relative to the file system location of the application's main executable assembly:

pack://application:,,,/Subfolder/ContentFile.xaml

Site of Origin File Pack URIs

The pack URI for a site of origin file uses the following authority and path:

  • Authority: siteoforigin:///.

  • Path: The name of the site of origin file, including its path relative to the location from which the executable assembly was launched.

The following example shows the pack URI for a XAML site of origin file, stored in the location from which the executable assembly is launched:

pack://siteoforigin:,,,/SiteOfOriginFile.xaml

The following example shows the pack URI for a XAML site of origin file, stored in subfolder of the location from which the executable assembly is launched:

pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml

Absolute vs Relative Pack URIs

A fully-qualified pack URI includes the scheme, the authority, and the path, and is considered an absolute pack URI. As a simplification for developers, XAML elements typically allow you to set appropriate attributes with a relative pack URI, which includes only the path.

For example, consider the following absolute pack URI for a resource file in the local assembly:

pack://application:,,,/ResourceFile.xaml

The relative pack URI that refers to this resource file would be the following:

/ResourceFile.xaml

NoteNote:

Because site of origin files have no association with assemblies, they can only be referred to using pack URIs.

By default, a relative pack URI reference is considered relative to the markup file or code file that contains the reference. If a leading backslash is used, however, the relative pack URI reference is then considered relative to the root of the application. For example, consider the following project structure:

App.xaml

Page2.xaml

\SubPages

Page1.xaml

Page2.xaml

If Page1.xaml wants to create a relative pack URI for the Page2.xaml file that is located in the SubPages folder, it can use the following:

Page2.xaml

However, if Page1.xaml wants to create a relative pack URI for the Page2.xaml file that is located in the root folder, it can use the following:

Page1.xaml

Pack URI Resolution

The format of pack URIs makes it is possible for a pack URI to look the same for both a local resource file and a content file:

pack://application:,,,/ResourceOrContentFile.xaml

The same is true for relative URIs:

/ResourceOrContentFile.xaml

Due to these similarities, WPF needs a way to determine whether pack URIs like these refer to either a resource file or a content file. Since a pack URI doesn't include this type of information, WPF uses resolves a URI using the following heuristics:

  1. Probe the assembly metadata for an AssemblyAssociatedContentFileAttribute that matches the pack URI.

  2. If the AssemblyAssociatedContentFileAttribute attribute is found, the path of the pack URI refers to a content file.

  3. If the AssemblyAssociatedContentFileAttribute attribute is not found, probe the set resource files that are compiled into the local assembly is enumerated.

  4. If a resource file that matches the path of the pack URI is found, the path of the pack URI refers to a resource file.

  5. If the resource is not found, the internally created Uri is invalid.

NoteNote:

Only absolute and relative pack URIs are included in resource resolution. Content files in referenced assemblies are not included because they are unsupported by WPF. Pack URIs for embedded files in referenced assemblies are unique because they include both the name of the referenced assembly and the ;component suffix. Pack URIs for site of origin files are unique because they use the are the only pack URIs that use the siteoforigin:/// authority.

WPF resource resolution allows you to create pack URIs that are independent of the locations of application data files. Consequently, if you change the build type of the non-executable data file from Resource to Content, for example, you don't have to change your pack URI.

Programming with Pack URIs

Many WPF classes implement properties that require pack URIs, including System.Windows.Application.StartupUri, System.Windows.Controls.Frame.Source, System.Windows.Navigation.NavigationWindow.Source, System.Windows.Documents.Hyperlink.NavigateUri, System.Windows.Window.Icon, and System.Windows.Controls.Image.Source.

These properties can be set from both markup and code.

Using Pack URIs in Markup

In markup, you specify a pack URI by setting the element of an attribute with the string value of the pack URI. For example:

<element attribute="pack://application:,,,/File.xaml" />

The following table illustrates the various absolute and relative pack URIs that you can specify using a string value in markup.

Table 1: Absolute and Relative Pack URIs in Markup

Non-Executable Data File Absolute Pack URI

Resource File - Local Assembly

Absolute

"pack://application:,,,/File.xaml"

Resource File in Subfolder - Local Assembly

Absolute

"pack://application:,,,/Subfolder/File.xaml"

Resource File - Referenced Assembly

Absolute

"pack://application:,,,/ReferencedAssembly;component/File.xaml"

Resource File in Subfolder - Referenced Assembly

Absolute

"pack://application:,,,/ReferencedAssembly;component/Subfolder/File.xaml"

Resource File - Versioned Referenced Assembly

Absolute

"pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/File.xaml"

Content File

Absolute

"pack://application:,,,/File.xaml"

Content File in Subfolder

Absolute

"pack://application:,,,/Subfolder/File.xaml"

Site of Origin File

Absolute

"pack://siteoforigin:,,,/File.xaml"

Site of Origin File in Subfolder

Absolute

"pack://siteoforigin:,,,/Subfolder/File.xaml"

Resource File - Local Assembly

Relative

"/File.xaml"

Resource File in Subfolder - Local Assembly

Relative

"/Subfolder/File.xaml"

Resource File - Referenced Assembly

Relative

"/ReferencedAssembly;component/File.xaml"

Resource File in Subfolder - Referenced Assembly

Relative

"/ReferencedAssembly;component/Subfolder/File.xaml"

Content File

Relative

"/File.xaml"

Content File in Subfolder

Relative

"/Subfolder/File.xaml"

NoteNote:

Site of origin files can only be referenced using absolute pack URIs.

Using Pack URIs in Code

In code, you specify a pack URI by instantiating Uri class and passing the pack URI as a parameter to the constructor. This is demonstrated in the following example:

Uri uri = new Uri("pack://application:,,,/File.xaml");

By default, the Uri class considers URI references to be absolute. Consequently, an exception is raised when you attempt to use an instance of the Uri class that references a relative pack URI:

Uri uri = new Uri("/File.xaml");

Fortunately, one overload of the Uri class constructor accepts a parameter of type UriKind, which allows you to specify whether a pack URI is either absolute or relative:

// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml", UriKind.Relative);

You should specify only Absolute or Relative when you are certain that the provided pack URI is one or the other. In some situations, however, you may not know whether a pack URI is absolute or relative at compile time. For example, an application may accept a user-provided pack URI at run time, in which case the pack URI might be either absolute or relative. In this case, you use RelativeOrAbsolute instead:

// Relative or Absolute URI
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);

The following table illustrates the various absolute and relative pack TLA2#tla_uri#plural that you can specify using the T:System.Uri in code.

Table 2: Absolute and Relative Pack URIs in Code

Non-Executable Data File Absolute Pack URI

Resource File - Local Assembly

Absolute

Uri uri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute");

Resource File in Subfolder - Local Assembly

Absolute

Uri uri = new Uri("pack://application:,,,/Subfolder/File.xaml", UriKind.Absolute");

Resource File - Referenced Assembly

Absolute

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/File.xaml", UriKind.Absolute");

Resource File in Subfolder - Referenced Assembly

Absolute

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/File.xaml", UriKind.Absolute");

Resource File - Versioned Referenced Assembly

Absolute

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/File.xaml", UriKind.Absolute");

Content File

Absolute

Uri uri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute");

Content File in Subfolder

Absolute

Uri uri = new Uri("pack://application:,,,/Subfolder/File.xaml", UriKind.Absolute");

Site of Origin File

Absolute

Uri uri = new Uri("pack://siteoforigin:,,,/File.xaml", UriKind.Absolute");

Site of Origin File in Subfolder

Absolute

Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/File.xaml", UriKind.Absolute");

Resource File - Local Assembly

Relative

Uri uri = new Uri("/File.xaml", UriKind.Relative");

Resource File in Subfolder - Local Assembly

Relative

Uri uri = new Uri("/Subfolder/File.xaml", UriKind.Relative");

Resource File - Referenced Assembly

Relative

Uri uri = new Uri("/ReferencedAssembly;component/File.xaml", UriKind.Relative");

Resource File in Subfolder - Referenced Assembly

Relative

Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/File.xaml", UriKind.Relative");

Content File

Relative

Uri uri = new Uri("/File.xaml", UriKind.Relative");

Content File in Subfolder

Relative

Uri uri = new Uri("/Subfolder/File.xaml", UriKind.Relative");

NoteNote:

Site of origin files can only be referenced using absolute pack URIs.

See Also

Concepts

Windows Presentation Foundation Application Data Files

Other Resources

Pack URI Sample