From 30538ba716c4177a5c6201c11430cadec9bbf6a0 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 8507dd57a1cb81a76d2dba2fbcfdbf9b834f6d52 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 11:29:43 -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 cd4fdbbbc67656de54ddd760802a15e3843d4581 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 11:51:02 -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 7232273c590d8531d6668c3878c93daa46c99491 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Thu, 21 May 2026 14:30:14 -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 8660146725ce60db2b2329c733ef24373d657897 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Fri, 22 May 2026 10:47:55 -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 300059187e0a32b53f15acbd938a9302ccee9898 Mon Sep 17 00:00:00 2001 From: guimafelipe Date: Fri, 22 May 2026 11:12:46 -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;