From 9d6b5a7cd94fead612cd01ac3ef9521241cdaf1d Mon Sep 17 00:00:00 2001 From: GabrielDuf Date: Mon, 8 Jun 2026 14:23:12 -0400 Subject: [PATCH 1/2] Fix Scoop shim failure under RedirectionGuard by retrying elevated --- .../Helpers/ScoopPkgOperationHelper.cs | 7 +++ .../ScoopManagerTests.cs | 45 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs index c2f74f00ef..b6b248f6a0 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs @@ -114,6 +114,13 @@ int returnCode return OperationVeredict.AutoRetry; } + // Scoop can't resolve shims through the fresh 'current' junction in some contexts; an elevated (trusted) junction fixes it. See #4892 + if (package.OverridenOptions.RunAsAdministrator != true && returnCode is not 0 && output_string.Contains("Can't shim")) + { + package.OverridenOptions.RunAsAdministrator = true; + return OperationVeredict.AutoRetry; + } + if (output_string.Contains("ERROR") || returnCode is not 0) return OperationVeredict.Failure; diff --git a/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs b/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs index 309693608b..319b0087ea 100644 --- a/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs +++ b/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs @@ -301,6 +301,51 @@ public void OperationResultPromotesElevationRetryBeforeReturningFailure() OperationAssert.HasVeredict(success, OperationVeredict.Success); } + [Fact] + public void OperationResultRetriesElevatedOnShimResolutionFailure() + { + var manager = new Scoop(); + var package = new PackageBuilder() + .WithManager(manager) + .WithOptions(new OverridenInstallationOptions(runAsAdministrator: false)) + .Build(); + + var retry = manager.OperationHelper.GetResult( + package, + OperationType.Update, + ["Creating shim for 'notepad++'.", "Can't shim 'notepad++.exe': File doesn't exist."], + 1 + ); + + OperationAssert.HasVeredict(retry, OperationVeredict.AutoRetry); + Assert.True(package.OverridenOptions.RunAsAdministrator); + + // Already elevated: the same failure must not loop, it should surface as a plain failure + var failure = manager.OperationHelper.GetResult( + package, + OperationType.Update, + ["Can't shim 'notepad++.exe': File doesn't exist."], + 1 + ); + OperationAssert.HasVeredict(failure, OperationVeredict.Failure); + } + + [Fact] + public void OperationResultDoesNotRetryShimMessageOnSuccess() + { + var manager = new Scoop(); + var package = new PackageBuilder().WithManager(manager).Build(); + + var veredict = manager.OperationHelper.GetResult( + package, + OperationType.Update, + ["Creating shim for 'tool'.", "Can't shim is mentioned but the operation succeeded"], + 0 + ); + + OperationAssert.HasVeredict(veredict, OperationVeredict.Success); + } + private static Scoop CreateManagerWithKnownSources(params string[] sourceNames) { var manager = new Scoop(); From d2907d6a535aab229a0d7da7216db446840659bc Mon Sep 17 00:00:00 2001 From: GabrielDuf Date: Mon, 8 Jun 2026 14:35:58 -0400 Subject: [PATCH 2/2] Don't auto-elevate Scoop shim retry when elevation is prohibited --- .../Helpers/ScoopPkgOperationHelper.cs | 10 +++++++-- .../ScoopManagerTests.cs | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs index b6b248f6a0..fb4f4942f7 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs @@ -1,3 +1,4 @@ +using UniGetUI.Core.SettingsEngine; using UniGetUI.PackageEngine.Classes.Manager.BaseProviders; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; @@ -114,8 +115,13 @@ int returnCode return OperationVeredict.AutoRetry; } - // Scoop can't resolve shims through the fresh 'current' junction in some contexts; an elevated (trusted) junction fixes it. See #4892 - if (package.OverridenOptions.RunAsAdministrator != true && returnCode is not 0 && output_string.Contains("Can't shim")) + // Scoop can't resolve shims through the fresh 'current' junction in some contexts; an elevated (trusted) junction fixes it, so retry as admin unless elevation is disabled. See #4892 + if ( + package.OverridenOptions.RunAsAdministrator != true + && returnCode is not 0 + && !Settings.Get(Settings.K.ProhibitElevation) + && output_string.Contains("Can't shim") + ) { package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; diff --git a/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs b/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs index 319b0087ea..028dd28213 100644 --- a/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs +++ b/src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs @@ -346,6 +346,27 @@ public void OperationResultDoesNotRetryShimMessageOnSuccess() OperationAssert.HasVeredict(veredict, OperationVeredict.Success); } + [Fact] + public void OperationResultDoesNotElevateShimFailureWhenElevationProhibited() + { + Settings.Set(Settings.K.ProhibitElevation, true); + var manager = new Scoop(); + var package = new PackageBuilder() + .WithManager(manager) + .WithOptions(new OverridenInstallationOptions(runAsAdministrator: false)) + .Build(); + + var veredict = manager.OperationHelper.GetResult( + package, + OperationType.Update, + ["Can't shim 'notepad++.exe': File doesn't exist."], + 1 + ); + + OperationAssert.HasVeredict(veredict, OperationVeredict.Failure); + Assert.False(package.OverridenOptions.RunAsAdministrator); + } + private static Scoop CreateManagerWithKnownSources(params string[] sourceNames) { var manager = new Scoop();