[2.0-stable] Gated cherry-pick: MrmGetFilePathFromName S_OK fallback (#6603) - #6612
Conversation
…/2.0-stable Cherry-picks PR #6603 into release/2.0-stable, but gates the behavior change behind a RuntimeCompatibilityOptions containment check so apps can disable it. MrmGetFilePathFromName is documented to always succeed and return a best-effort path even when no PRI file exists. On 2.0-stable it fails with ERROR_FILE_NOT_FOUND, which makes `new ResourceManager()` throw when there is no resources.pri (the XAML-island / no-PRI scenario). Because this changes an HRESULT from a failure to S_OK, the change is contained under WINAPPSDK_CHANGEID_63048673: - Enabled (default): MrmGetFilePathFromName returns S_OK with a non-null best-effort path (the provided filename, else resources.pri) under the base directory (if set) otherwise the module directory. - Disabled (via RuntimeCompatibilityOptions): behavior reverts byte-for-byte to the current 2.0-stable behavior (ERROR_FILE_NOT_FOUND). Both terminal search passes jump to Final, skipping the DefaultFallback pass. Changes: - MRM.cpp: gate the reachable DefaultFallback pass + S_OK return on IsChangeEnabled<WINAPPSDK_CHANGEID_63048673>(). Add #include <FrameworkUdk/Containment.h> and an inline #define for the change ID, following the existing 62382643 precedent in Helper.cpp. Preserve the module directory since the parent-folder search mutates exeDir in place. - MRM.vcxproj: link the FrameworkUdk Containment worker (targets import + EnsureNuGetPackageBuildImports). - MrmUnitTest.vcxproj: deploy Microsoft.Internal.FrameworkUdk.dll next to the test host (mrm.dll now imports it). - Helper.cpp (GetDefaultPriFile): inside the existing 62382643 block, gate the sparse-packaged [modulename].pri fallback on actual file existence (CheckFile) so it still fires once MrmGetFilePathFromName returns S_OK. Correct whether 63048673 is enabled or disabled; preserves 62382643 behavior. - MrmTests.cpp: strengthen GetFilePath to assert the fallback path is under the module directory. - BypassTests.json: remove the now-passing UnitTest::BasicTest::GetFilePath and MrtCoreUnpackagedTests.TestClass.DefaultResourceManager entries so they gate. Note for release engineering: per the ContainmentV2 model this PR only defines and gates the change ID; associating 63048673 to a release group in RuntimeCompatibilityOptions.cpp's s_catalogGroupsProd[] is the separate branch-cut step. Verified locally (x64 Debug): MrmUnitTest 21/21 (change enabled by default). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Hello, Scott Jones (@Scottj1s) ! Will you also backport it to 1.8? (Is 1.8 still under maintaince?) As far as I know, WinUI3 1.8+ is affected by this PR. |
Yes, I'll backport to 1.8 as well: #6617 |
…abled Adds ContainmentDisabledTest::GetFilePathFallbackDisabled to MrmUnitTest. It disables WINAPPSDK_CHANGEID_63048673 via the FrameworkUdk containment worker (WinAppSdk::Containment::SetConfiguration) and verifies MrmGetFilePathFromName reverts to the previous behavior: ERROR_FILE_NOT_FOUND (null path) for a non-existent PRI file, instead of S_OK with a best-effort path. The class uses IsolationLevel=Method so it runs in its own process. This is required because IsChangeEnabled<>() caches its result in a process-lifetime function-local static, so the disabled-state test must not share a process with BasicTest::GetFilePath (which exercises the enabled default state). MrmUnitTest.vcxproj: import the FrameworkUdk targets so the test can call the Containment worker (mrm.dll already imports Microsoft.Internal.FrameworkUdk.dll, deployed next to the test host). Verified locally (x64 Debug): MrmUnitTest 22/22, including both the enabled (GetFilePath) and disabled (GetFilePathFallbackDisabled) cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Scott Jones (@Scottj1s) I have a little question: after this PR merged, will the fix be enabled or disabled by default? If disabled by default, how to enable it explicitly? Or, is there a way to detect whether it is enabled? |
Yuyi Wang (@Berrysoft), All servicing fixes, including this one, are enabled by default. Disabling is an explicit action - e.g., see the GetFilePathFallbackDisabled test case. |
…6603) (#6617) Ports the MrmGetFilePathFromName fix (main #6603, also cherry-picked to release/2.0-stable in #6612) into release/1.8-stable, gated behind a runtime-compatibility containment change so apps can disable it. MrmGetFilePathFromName is documented to always succeed and return a best-effort path even when no PRI file exists. On 1.8-stable it fails with ERROR_FILE_NOT_FOUND, which makes `new ResourceManager()` throw when there is no resources.pri (the XAML-island / no-PRI scenario - issue #5814). 1.8 uses the ContainmentV1 model where IsChangeEnabled requires a target patch version, so the change ID macro bakes it in: #define WINAPPSDK_CHANGEID_63048673 63048673, WinAppSDK_1_8_11 - Enabled (runtime at/after 1.8.11, default): MrmGetFilePathFromName returns S_OK with a non-null best-effort path (the provided filename, else resources.pri) under the base directory (if set) otherwise the module directory. - Disabled (via RuntimeCompatibilityOptions) or runtime pinned before 1.8.11: behavior reverts byte-for-byte to current 1.8-stable (ERROR_FILE_NOT_FOUND). Both terminal search passes jump to Final, skipping the DefaultFallback pass. Changes: - MRM.cpp: gate the reachable DefaultFallback pass + S_OK return on IsChangeEnabled<WINAPPSDK_CHANGEID_63048673>() (2-arg ContainmentV1 form). Add #include <FrameworkUdk/Containment.h> and the inline #define. Preserve the module directory since the parent-folder search mutates exeDir in place. - MRM.vcxproj: link the FrameworkUdk Containment worker (targets import + EnsureNuGetPackageBuildImports). - MrmUnitTest.vcxproj: link FrameworkUdk and deploy Microsoft.Internal.FrameworkUdk.dll next to the test host. - MrmTests.cpp: strengthen GetFilePath to assert the fallback path is under the module directory; add ContainmentDisabledTest (IsolationLevel=Method) that disables 63048673 via SetConfiguration and verifies the pre-fix ERROR_FILE_NOT_FOUND behavior. - BypassTests.json: remove the now-passing UnitTest::BasicTest::GetFilePath and MrtCoreUnpackagedTests.TestClass.DefaultResourceManager entries so they gate. Helper.cpp is intentionally NOT changed: 1.8 has no sparse-packaged PRI fallback block (that came later), so the S_OK result flows through GetDefaultPriFile without adjustment. Verified locally (x64 Debug): MrmUnitTest 22/22, including both the enabled (GetFilePath) and disabled (GetFilePathFallbackDisabled) cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cherry-picks #6603 into
release/2.0-stable, gated behind a RuntimeCompatibilityOptions containment check so apps can disable it.Background
MrmGetFilePathFromNameis documented to always succeed and return a best-effort path even when no PRI file exists. Onrelease/2.0-stableit fails withERROR_FILE_NOT_FOUND, which makesnew ResourceManager()throw when there is noresources.pri(the XAML-island / no-PRI scenario — original issues #5814 / #5940, fixed onmainby #6603).Containment
Because this flips an HRESULT from a failure to
S_OK, the change is contained underWINAPPSDK_CHANGEID_63048673:MrmGetFilePathFromNamereturnsS_OKwith a non-null best-effort path (the provided filename, elseresources.pri) under the base directory (if set) otherwise the module directory.RuntimeCompatibilityOptions/WindowsAppSDKDisabledChanges): behavior reverts byte-for-byte to currentrelease/2.0-stable(ERROR_FILE_NOT_FOUND). Both terminal search passes jump toFinal, skipping theDefaultFallbackpass.The gate is placed in
MrmGetFilePathFromNameitself, so it contains the public export's HRESULT flip for bothResourceManagerand any direct external callers.Changes
DefaultFallbackpass +S_OKreturn onIsChangeEnabled<WINAPPSDK_CHANGEID_63048673>(). Adds#include <FrameworkUdk/Containment.h>+ an inline#definefor the change ID (following the existing62382643precedent in Helper.cpp). Preserves the module directory since the parent-folder search mutatesexeDirin place.EnsureNuGetPackageBuildImports).Microsoft.Internal.FrameworkUdk.dllnext to the test host (mrm.dllnow imports it).GetDefaultPriFile) — inside the existing62382643block, gate the sparse-packaged[modulename].prifallback on actual file existence (CheckFile) so it still fires onceMrmGetFilePathFromNamereturnsS_OK. Correct whether63048673is enabled or disabled; preserves62382643behavior.GetFilePathto assert the fallback path is under the module directory.UnitTest::BasicTest::GetFilePathandMrtCoreUnpackagedTests.TestClass.DefaultResourceManagerentries so they gate again.Note for release engineering
Per the ContainmentV2 model this PR only defines and gates the change ID. Associating
63048673to a release group inRuntimeCompatibilityOptions.cpp'ss_catalogGroupsProd[]is the separate branch-cut step (same as the existing62382643).Validation
Built
MrtCore.slnnative projects (x64 Debug) locally;MrmUnitTest21/21 (change enabled by default,GetFilePathreturnsS_OKwith a valid module-dir path). Disabled-path behavior is byte-equivalent to currentrelease/2.0-stableby construction. The Helper.cpp logic is identical to #6603, validated 27/27 (incl.DefaultResourceManager) onmain.