microsoft / microsoft/WindowsAppSDK
LoadComponent fails for XAML pages in subfolders — embedded XBF indexed by filename only, URI includes subdirectory path
@guimafelipe is already working on this.
Since Mar 19, 2026.
- Dominant language
- C++
- Stars
- 4.7k
- Forks
- 471
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 28
Description
Describe the bug
Apps with XAML pages organized in subdirectories (e.g. Presentation\Shell.xaml) crash at startup with:
Cannot locate resource from 'ms-appx:///Presentation/Shell.xaml'
or in Uno Platform apps:
Layout cycle detected. Layout is not able to complete.
This is a silent build-time/runtime mismatch — the app builds without errors or warnings but crashes at runtime.
Root cause
The _CalculateXbfSupport target in Microsoft.Build.Msix.Pri.targets (shipped inside the Microsoft.WindowsAppSDK NuGet package since version 1.0.0) sets _SupportXbfAsEmbedFileResources=true by default:
<Target Name="_CalculateXbfSupport">
<PropertyGroup>
<_SupportXbfAsEmbedFileResources Condition="'$(_SupportEmbedFileResources)' == 'true' and '$(DisableEmbeddedXbf)' == 'false'">true</_SupportXbfAsEmbedFileResources>
<_SupportXbfAsEmbedFileResources Condition="'$(DisableEmbeddedXbf)' == 'true'">false</_SupportXbfAsEmbedFileResources>
<_SupportXbfAsEmbedFileResources Condition="'$(_SupportXbfAsEmbedFileResources)' == '' AND '$(_SupportEmbedFileResources)' == 'true'">true</_SupportXbfAsEmbedFileResources>
</PropertyGroup>
</Target>
This causes XBF files to be routed to EmbedOutputGroupForPackaging in the GetPriOutputs target:
<_PriOutputsUnexpanded Include="@(_CustomOutputGroupForPackagingOutput)"
Condition="'%(Extension)' == '.xbf' AND '$(_SupportXbfAsEmbedFileResources)' == 'true'">
<OutputGroup>EmbedOutputGroupForPackaging</OutputGroup>
</_PriOutputsUnexpanded>
Files in EmbedOutputGroupForPackaging are embedded as binary blobs in resources.pri and indexed only by their filename — the subdirectory prefix is stripped. So Presentation\Shell.xbf becomes Files/Shell.xbf in resources.pri.
Meanwhile, the XAML compiler (Microsoft.WinUI.NET.Markup.Compiler.targets) generates LoadComponent URIs from the Page item's %(Link) metadata — or the project-relative path if Link is not set. Without explicit Link, it emits ms-appx:///Presentation/Shell.xaml, which does not match the flat Files/Shell.xbf in resources.pri.
XAML compiler DLL versions
| WinAppSDK | Compiler DLL version | Package |
|---|---|---|
| 1.7 | 3.0.0.2509 |
Microsoft.WindowsAppSDK |
| 1.8 | 3.0.0.2602 |
Microsoft.WindowsAppSDK.WinUI (new sub-package) |
The PRI targets (_CalculateXbfSupport, GetPriOutputs) are identical across versions 1.0 through 1.8.
Steps to reproduce
- Create an unpackaged WinUI 3 app (
WindowsPackageType=None) - Add a
PageXAML file in a subfolder (e.g.Presentation\MainPage.xaml) - Build and run → crashes with
Cannot locate resource from 'ms-appx:///Presentation/MainPage.xaml'
Reproduces with both pure WinUI 3 projects and Uno Platform single-project apps targeting net10.0-windows10.0.26100.
Note: The Uno SDK's Uno.DefaultItems.targets includes XAML pages via <Page Include="**\*.xaml" .../> without setting Link metadata — this is the source of the mismatch for projects that organize XAML files in subdirectories.
Expected behavior
XAML pages placed in subdirectories load correctly. The LoadComponent URI must match the PRI resource index path.
Actual behavior
App crashes at startup — LoadComponent cannot find the resource because the PRI entry is indexed by flat filename (Files/Shell.xbf) while the XAML compiler generates a URI with the subdirectory path (ms-appx:///Presentation/Shell.xaml).
Workaround
Set <Link>%(Filename)%(Extension)</Link> on all Page items to force the XAML compiler to emit flat ms-appx:/// URIs that match the embedded XBF index:
<!-- Directory.Build.targets -->
<ItemGroup Condition="$(IsWinAppSdk) == 'true'
AND ('$(OutputType)'=='Exe' OR '$(OutputType)'=='WinExe')">
<!--
XBF files are embedded in resources.pri and indexed by filename only (no path).
Without Link, XamlCompiler generates ms-appx:///Subfolder/Page.xaml URIs
that don't match the flat Files/Page.xbf entries.
IMPORTANT: XAML files must have unique names across all subfolders.
-->
<Page Update="**\*.xaml">
<Link>%(Filename)%(Extension)</Link>
</Page>
<Page Update="App.xaml">
<Link>App.xaml</Link>
</Page>
</ItemGroup>
Limitation: XamlCompiler.exe always names output XBF by the source %(Filename) (ignoring Link path prefix). XAML files in the same executable project must have unique filenames across all subdirectories — two files with the same name in different folders (e.g. Views\Page.xaml and Controls\Page.xaml) cause an MSB3030 copy error.
Suggested fix
The embedded XBF indexer should preserve the relative path in the PRI index (e.g. Files/Presentation/Shell.xbf instead of Files/Shell.xbf), OR the XAML compiler should automatically set Link to match the flat index when _SupportXbfAsEmbedFileResources=true.
NuGet package versions
| Package | Version |
|---|---|
Microsoft.WindowsAppSDK |
1.8.260209005 |
Microsoft.Windows.SDK.BuildTools |
10.0.28000.1-RTM |
Packaging type
Unpackaged (WindowsPackageType=None)
Windows version
Windows 11 24H2 (Build 26100)
Additional context
- Related issue: #5832 ("Upgrading to v1.8 breaks ResourceLoader in unpackaged apps") — same PRI area, different symptom
- The
embed.resfilesintermediate file lists XBF entries by flat filename, confirming paths are stripped - This affects any framework built on top of WinUI 3 that uses subdirectory XAML organization (Uno Platform, etc.)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.