Skip to content

Commit f260e6c

Browse files
authored
Retry Chocolatey operations elevated when a package script demands admin (#5495)
1 parent 5483d8f commit f260e6c

2 files changed

Lines changed: 103 additions & 0 deletions

File tree

‎src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using UniGetUI.Core.SettingsEngine;
12
using UniGetUI.Core.Tools;
23
using UniGetUI.PackageEngine.Classes.Manager.BaseProviders;
34
using UniGetUI.PackageEngine.Enums;
@@ -89,6 +90,7 @@ int returnCode
8990
string output_string = string.Join("\n", processOutput);
9091
if (
9192
package.OverridenOptions.RunAsAdministrator != true
93+
&& !Settings.Get(Settings.K.ProhibitElevation)
9294
&& (
9395
output_string.Contains("Run as administrator")
9496
|| output_string.Contains("The requested operation requires elevation")
@@ -99,6 +101,8 @@ int returnCode
99101
"WARNING: Unable to create shortcut. Error captured was Unable to save shortcut"
100102
)
101103
|| output_string.Contains("access denied")
104+
|| output_string.Contains("requires Administrative permissions")
105+
|| output_string.Contains("run from elevated prompt")
102106
)
103107
)
104108
{

‎src/UniGetUI.PackageEngine.Tests/ChocolateyManagerTests.cs‎

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,105 @@ public void OperationResultPromotesElevationFailuresToAutoRetry()
288288
Assert.True(package.OverridenOptions.RunAsAdministrator);
289289
}
290290

291+
private static readonly string[] NonElevatedBanner =
292+
[
293+
"Chocolatey v2.4.3",
294+
"Chocolatey detected you are not running from an elevated command shell",
295+
" (cmd/powershell).",
296+
"",
297+
" You may experience errors - many functions/packages",
298+
" require admin rights. Only advanced users should run choco w/out an",
299+
" elevated shell. When you open the command shell, you should ensure",
300+
" that you do so with \"Run as Administrator\" selected. If you are",
301+
" attempting to use Chocolatey in a non-administrator setting, you",
302+
" must select a different location other than the default install",
303+
" location. See",
304+
" https://docs.chocolatey.org/en-us/choco/setup#non-administrative-install",
305+
" for details.",
306+
"For the question below, you have 20 seconds to make a selection.",
307+
" Do you want to continue?([Y]es/[N]o): ",
308+
"Timeout or your choice of '' is not a valid selection.",
309+
];
310+
311+
private const string PackageScriptAdminError =
312+
"ERROR: Installation of python314 to default folder requires Administrative permissions. Please run from elevated prompt.";
313+
314+
private static string[] NonElevatedFailure(string errorLine) =>
315+
[
316+
.. NonElevatedBanner,
317+
"Installing 64-bit python314...",
318+
"python314 has been installed.",
319+
errorLine,
320+
"The upgrade of python314 was NOT successful.",
321+
"Chocolatey upgraded 0/3 packages. 3 packages failed.",
322+
];
323+
324+
[Theory]
325+
[InlineData(PackageScriptAdminError)]
326+
[InlineData("ERROR: Installation of examplepkg requires Administrative permissions.")]
327+
[InlineData("ERROR: examplepkg cannot be installed here. Please run from elevated prompt.")]
328+
public void OperationResultPromotesPackageScriptAdminRequirementToAutoRetry(string errorLine)
329+
{
330+
var manager = new Chocolatey();
331+
var package = new PackageBuilder()
332+
.WithManager(manager)
333+
.WithOptions(new OverridenInstallationOptions(runAsAdministrator: false))
334+
.Build();
335+
336+
var veredict = manager.OperationHelper.GetResult(
337+
package,
338+
OperationType.Update,
339+
NonElevatedFailure(errorLine),
340+
-1
341+
);
342+
343+
OperationAssert.HasVeredict(veredict, OperationVeredict.AutoRetry);
344+
Assert.True(package.OverridenOptions.RunAsAdministrator);
345+
}
346+
347+
[Fact]
348+
public void OperationResultDoesNotElevateOnTheNonElevatedBannerAlone()
349+
{
350+
var manager = new Chocolatey();
351+
var package = new PackageBuilder()
352+
.WithManager(manager)
353+
.WithOptions(new OverridenInstallationOptions(runAsAdministrator: false))
354+
.Build();
355+
356+
var veredict = manager.OperationHelper.GetResult(
357+
package,
358+
OperationType.Update,
359+
NonElevatedFailure(
360+
"ERROR: The install script of examplepkg exited with an unexpected error."
361+
),
362+
-1
363+
);
364+
365+
OperationAssert.HasVeredict(veredict, OperationVeredict.Failure);
366+
Assert.NotEqual(true, package.OverridenOptions.RunAsAdministrator);
367+
}
368+
369+
[Fact]
370+
public void OperationResultDoesNotRetryWhenElevationIsProhibited()
371+
{
372+
Settings.Set(Settings.K.ProhibitElevation, true);
373+
var manager = new Chocolatey();
374+
var package = new PackageBuilder()
375+
.WithManager(manager)
376+
.WithOptions(new OverridenInstallationOptions(runAsAdministrator: false))
377+
.Build();
378+
379+
var veredict = manager.OperationHelper.GetResult(
380+
package,
381+
OperationType.Update,
382+
NonElevatedFailure(PackageScriptAdminError),
383+
-1
384+
);
385+
386+
OperationAssert.HasVeredict(veredict, OperationVeredict.Failure);
387+
Assert.NotEqual(true, package.OverridenOptions.RunAsAdministrator);
388+
}
389+
291390
[Fact]
292391
public void OperationResultReturnsFailureWhenElevationWasAlreadyRequested()
293392
{

0 commit comments

Comments
 (0)