From 234bf70aa0c9b9721a285b46aeea57aa89467ec4 Mon Sep 17 00:00:00 2001 From: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:44:22 +0800 Subject: [PATCH 1/6] Fix sparse-packaged apps unable to discover module-specific PRI files (#6376) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix sparse-packaged apps unable to discover module-specific PRI files Sparse-packaged apps have package identity (via AddPackageByUriAsync) but deploy resources as loose files next to the executable. GetDefaultPriFile() determines isPackaged=true for these apps (since they have identity), causing GetDefaultPriFileForCurentModule to pass "resources.pri" to MrmGetFilePathFromName — which only searches for that exact filename, skipping the [modulename].pri fallback that unpackaged apps receive. When the "resources.pri" search fails for apps with identity, fall back to the unpackaged discovery path (pass nullptr to MrmGetFilePathFromName) which triggers the broader search including "[modulename].pri" derived via PathCchRenameExtension from the process executable name. If the fallback also fails, return the original HRESULT from the "resources.pri" search so callers that check for specific errors (e.g., ERROR_FILE_NOT_FOUND) are not broken. Existing test coverage: - DefaultResourceManagerWithExePri validates the nullptr fallback mechanism - DefaultResourceManager validates error behavior when no PRI exists - DefaultResourceManagerWithResourcePri validates the normal packaged path A full sparse-app integration test requires actual sparse package registration (AddPackageByUriAsync) which is beyond unit test scope. Fixes: https://github.com/microsoft/microsoft-ui-xaml/issues/10856 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: simplify flow, shorten comment, gate on file-not-found * Add backward-compatibility comment on return hr * Move backward-compat comment to fallback block for clarity * Keep comment sentences on single lines * Use existing IsResourceNotFound() helper instead of manual HRESULT checks * Merge two-line comment into single line Agent-Logs-Url: https://github.com/microsoft/WindowsAppSDK/sessions/ed36cfc6-52ad-414b-8e1a-dc16f413a97e Co-authored-by: yeelam-gordon <73506701+yeelam-gordon@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- .../src/Helper.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index f502592f7c..58d419c808 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -84,5 +84,19 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) // GetDefaultPriFileForCurrentPackage will not handle the new case where // resources.pri is in the parent folder. bool isPackaged = (hr != HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)); - return GetDefaultPriFileForCurentModule(isPackaged, filePath); + hr = GetDefaultPriFileForCurentModule(isPackaged, filePath); + + // Sparse-packaged apps have identity but deploy PRI files as loose files; fall back to unpackaged discovery which also searches for "[modulename].pri". + if (isPackaged && IsResourceNotFound(hr)) + { + HRESULT hrFallback = GetDefaultPriFileForCurentModule(false, filePath); + if (SUCCEEDED(hrFallback)) + { + hr = hrFallback; + } + // If the fallback also fails, preserve the original HRESULT (not the fallback's) + // for backward compatibility so callers checking for specific errors (e.g., ERROR_FILE_NOT_FOUND) are not broken. + } + + return hr; } From b3845c7204c388d8f1f6f3181d3b4c65f16c3656 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 11:29:38 -0700 Subject: [PATCH 2/6] Add containment for sparse PRI fallback fix Bug 62382643: gate the sparse PRI fallback with containment so it can be rolled back if needed. --- .../src/Helper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 58d419c808..36a2cb9455 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -1,8 +1,12 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #include "pch.h" #include "frameworkudk\ResourceManager.h" +#include + +// Bug PLACEHOLDER: Fix sparse-packaged apps unable to discover module-specific PRI files +#define WINAPPSDK_CHANGEID_62382643 62382643, WinAppSDK_2_1_1 bool IsResourceNotFound(HRESULT hr) { @@ -87,7 +91,8 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) hr = GetDefaultPriFileForCurentModule(isPackaged, filePath); // Sparse-packaged apps have identity but deploy PRI files as loose files; fall back to unpackaged discovery which also searches for "[modulename].pri". - if (isPackaged && IsResourceNotFound(hr)) + if (WinAppSdk::Containment::IsChangeEnabled() && + isPackaged && IsResourceNotFound(hr)) { HRESULT hrFallback = GetDefaultPriFileForCurentModule(false, filePath); if (SUCCEEDED(hrFallback)) From 7e8a79b81167bef985104eecd609212238e3bef5 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 11:50:57 -0700 Subject: [PATCH 3/6] Fix containment version to WinAppSDK_2_1_5 --- .../Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 36a2cb9455..5fbe396707 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -6,7 +6,7 @@ #include // Bug PLACEHOLDER: Fix sparse-packaged apps unable to discover module-specific PRI files -#define WINAPPSDK_CHANGEID_62382643 62382643, WinAppSDK_2_1_1 +#define WINAPPSDK_CHANGEID_62382643 62382643, WinAppSDK_2_1_5 bool IsResourceNotFound(HRESULT hr) { From a54f6cce87c176fc0839d7f58799bb983f1ba3f1 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 14:30:09 -0700 Subject: [PATCH 4/6] Fix bug ID in containment comment --- .../Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 5fbe396707..2e8dd6edfe 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -5,7 +5,7 @@ #include "frameworkudk\ResourceManager.h" #include -// Bug PLACEHOLDER: Fix sparse-packaged apps unable to discover module-specific PRI files +// Bug 62382643: Fix sparse-packaged apps unable to discover module-specific PRI files #define WINAPPSDK_CHANGEID_62382643 62382643, WinAppSDK_2_1_5 bool IsResourceNotFound(HRESULT hr) From 77dcff51b66509901ef9e4757fc09e63af603193 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Fri, 22 May 2026 10:47:50 -0700 Subject: [PATCH 5/6] Contain all changed code inside containment gate --- .../src/Helper.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 2e8dd6edfe..7504a1ffe5 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -88,20 +88,26 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) // GetDefaultPriFileForCurrentPackage will not handle the new case where // resources.pri is in the parent folder. bool isPackaged = (hr != HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)); - hr = GetDefaultPriFileForCurentModule(isPackaged, filePath); - // Sparse-packaged apps have identity but deploy PRI files as loose files; fall back to unpackaged discovery which also searches for "[modulename].pri". - if (WinAppSdk::Containment::IsChangeEnabled() && - isPackaged && IsResourceNotFound(hr)) + if (WinAppSdk::Containment::IsChangeEnabled()) { - HRESULT hrFallback = GetDefaultPriFileForCurentModule(false, filePath); - if (SUCCEEDED(hrFallback)) + hr = GetDefaultPriFileForCurentModule(isPackaged, filePath); + + // Sparse-packaged apps have identity but deploy PRI files as loose files; + // fall back to unpackaged discovery which also searches for "[modulename].pri". + if (isPackaged && IsResourceNotFound(hr)) { - hr = hrFallback; + HRESULT hrFallback = GetDefaultPriFileForCurentModule(false, filePath); + if (SUCCEEDED(hrFallback)) + { + hr = hrFallback; + } + // If the fallback also fails, preserve the original HRESULT (not the fallback's) + // for backward compatibility so callers checking for specific errors (e.g., ERROR_FILE_NOT_FOUND) are not broken. } - // If the fallback also fails, preserve the original HRESULT (not the fallback's) - // for backward compatibility so callers checking for specific errors (e.g., ERROR_FILE_NOT_FOUND) are not broken. + + return hr; } - return hr; + return GetDefaultPriFileForCurentModule(isPackaged, filePath); } From 68c36d91dea8bfa8d677aa53e34ee5cd04a3fb0e Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Fri, 22 May 2026 11:12:41 -0700 Subject: [PATCH 6/6] Use IsPackagedProcess() for package detection inside containment --- .../Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 7504a1ffe5..6b79268695 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include "frameworkudk\ResourceManager.h" #include +#include // Bug 62382643: Fix sparse-packaged apps unable to discover module-specific PRI files #define WINAPPSDK_CHANGEID_62382643 62382643, WinAppSDK_2_1_5 @@ -91,6 +92,7 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) if (WinAppSdk::Containment::IsChangeEnabled()) { + isPackaged = AppModel::Identity::IsPackagedProcess(); hr = GetDefaultPriFileForCurentModule(isPackaged, filePath); // Sparse-packaged apps have identity but deploy PRI files as loose files;