Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using UniGetUI.Core.SettingsEngine;
using UniGetUI.PackageEngine.Classes.Manager.BaseProviders;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
Expand Down Expand Up @@ -114,6 +115,18 @@ int returnCode
return OperationVeredict.AutoRetry;
}

// 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;
}

if (output_string.Contains("ERROR") || returnCode is not 0)
return OperationVeredict.Failure;

Expand Down
66 changes: 66 additions & 0 deletions src/UniGetUI.PackageEngine.Tests/ScoopManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,72 @@ 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);
}

[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();
Expand Down
Loading