Upgrading to v1.8 breaks ResourceLoader in unpackaged apps
Describe the bug
When updating from v1.7 to v1.8 my app (DLSS Swapper) no longer launches. Constructing Windows.ApplicationModel.Resources.ResourceLoader causes the app to crash. There is a repro linked below.
The error appears to come from WinRT.Runtime.dll and is
System.IO.FileNotFoundException: Unable to find the specified file.
The full stacktrace is,
at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr) at WinRT.ExceptionHelpers.ThrowExceptionForHR(Int32 hr) at ABI.WinRT.Interop.IActivationFactoryMethods.ActivateInstanceUnsafe(IObjectReference objectReference, Guid iid) at Windows.ApplicationModel.Resources.ResourceLoader..ctor() at ResourceLoaderTest.MainWindow.Grid_Loaded(Object sender, RoutedEventArgs e) in D:\git\beeradmoore\WindowsAppSDK_ResourceLoaderIssue\ResourceLoaderTest\ResourceLoaderTest\MainWindow.xaml.cs:line 37
I was not able to reproduce the issue in a packaged app.
Comparing the files in bin between the two I notice that v1.7 produces resources.pri whereas v1.8 produces ResourceLoaderTest.pri. If I put the app config in its broken state and confirm it does not work as intended, but then copy/paste ResourceLoaderTest.pri to resources.pri it will now work as expected.
Steps to reproduce the bug
See the project in this repo: https://github.com/beeradmoore/WindowsAppSDK_ResourceLoaderIssue
- Run the project in debug mode (runs as unpackaged by default).
- Observe that the first
Debugger.Break();is hit indicatingResourceLoaderconstructed - Update nuget package from 1.7.250606001 to 1.8.250907003
- Run the project again and now observe you hit the
Debugger.Break();in the catch statement.
Expected behavior
The first Debugger.Break(); is hit in both cases.
Screenshots
No response
NuGet package version
Windows App SDK 1.8.0: 1.8.250907003
Packaging type
Unpackaged
Windows version
Windows 11 version 24H2 (26100, June 2025 Update)
IDE
Visual Studio 2022
Additional context
No response
See #5746
This looks like it is a long running issue with the single project packaging tools. When the project that has been set to unpackaged has EnableMsixTooling in the project file, 1.7 and older just produced resources.pri. But if you remove EnableMsixTooling or even started from the WinUI Blank App (Packaged with Windows Application Packaging Project), or any older iterations of this, then it would alwas produce <executable_name>.pri.
Yep, I can confirm setting EnableMsixTooling to false or removing it completly results in the same crash because the pri is <executable_name>.pri in v1.7. In v1.8 the pri is always <executable_name>.pri no matter what this setting is.
There are some comments here about MrmGetFilePathFromName which may be related. But the comments also seem to make it sound like it looks for [modulename].pri and then resources.pri if it is not found.
I am unsure if the code is broken here, or if this is just not part of this execution path for the exception we are seeing and the code that is running is still specifically looking for resources.pri.
The problem with MrmGetFilePathFromName should be unrelated, since this is part of MRT Core. Windows.ApplicationModel.Resources.ResourceLoader, AKA MRT, is a completely separate component not tied to the Windows App SDK and MRT Core. In this case, MRT (not MRT Core) was designed exclusively for UWP applications, which should always be packaged. This means that resources.pri is a safe bet since it should always be made as part of the packaging process. MRT Core took unpackaged desktop applications into account and so it started looking for [modulename].pri first, but this was not back ported to MRT.
In the end, we still need confirmation as to whether the older single project packaging tools producing resources.pri when the project was set to unpackaged was a bug. If it was, then an unpackaged application should have always been required to produce resources.pri somehow. Copying [executable].pri would be the best option here. If it wasn't, then that means that the Windows App SDK ended up producing the wrong file name in the majority of cases, which is bad. It is also problematic for non WinUI 3 use of the Windows App SDK and MRT Core.
We have this issue while using the latest Syncfusion SfRibbon component. Renaming the file [executable].pri to resources.pri solves it.
The latest release of Syncfusion's WinUI3 suite (31.2.2) together with the WinAPPSDK 1.8.251003001 resolved our issue,
I modified the csproj to automatically rename the pri file to resources.pri.
Include the below line in .csproj after </PropertyGroup>
<Import Project="RenamePriFile.targets" />
And create a file called RenamePriFile.targets with the below content and include it in your project root.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="RenamePriFile" AfterTargets="Build">
<!-- Define variables for clarity. Adjust as necessary. -->
<PropertyGroup>
<!-- The default name of the generated .pri file is typically the AssemblyName + .pri -->
<OriginalPriFile>$(TargetDir)$(AssemblyName).pri</OriginalPriFile>
<!-- The new desired name for your .pri file -->
<NewPriFile>$(TargetDir)resources.pri</NewPriFile>
</PropertyGroup>
<!-- Use the "Move" task to rename/move the file -->
<Move SourceFiles="$(OriginalPriFile)"
DestinationFiles="$(NewPriFile)"
ContinueOnError="false" />
</Target>
</Project>
@gautambjain , I finally got around to trying this. I had to change this to Copy instead of `Move. For some reason when I run my publish scripts I'd get
C:\Program Files\dotnet\sdk\10.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(371,5): error MSB3030: Could not copy the file "D:\git\dlss-swapper\src\bin\Release_Portable\net10.0-windows10.0.26100.0\win-x64\DLSS Swapper.pri" because it was not found.
Unsure if this is because of .NET 10 or because I have updated to WindowsAppSDK v1.8.251106002, but either way that above props file works after I update it.
Right, certain build sequence may require a "Copy" instead of "Move".
Just to add on to this further incase it helps someone else. I publish my app with dotnet publish ... and this didn't run because it first builds to a build folder then to the publish folder for some reason. But adding a second target and using for AfterPublish $(PublishDir) fixes it.
<Target Name="CopyPriFilePublish" AfterTargets="Publish">
<!-- Define variables for clarity. Adjust as necessary. -->
<PropertyGroup>
<!-- The default name of the generated .pri file is typically the AssemblyName + .pri -->
<OriginalPriFile>$(PublishDir)$(AssemblyName).pri</OriginalPriFile>
<!-- The new desired name for your .pri file -->
<NewPriFile>$(PublishDir)resources.pri</NewPriFile>
</PropertyGroup>
<!-- Use the "Copy" task to duplicate the file -->
<Copy SourceFiles="$(OriginalPriFile)"
DestinationFiles="$(NewPriFile)"
ContinueOnError="false" />
</Target>
I have hit the same issue on ResourceLoader.GetForViewIndependentUse() crashing in upackaged mode only after updating to the 1.8.x branch of APP SDK. The rename solution fixes my case as well.
What is not clear to me if there is any official acknowledgement or plan to fix the problems that are being reported in this repository, or we are left with community provided workarounds that might break at any time. Also the MRT vs MRT Core implementations, elsewhere it is suggested to completely avoid using the Windows.xxx (MRT) API in Unpackaged, yet it is somehow changing its behavior between releases focusing on MRT Core APIs