Skip to content

Commit f20c4c1

Browse files
committed
WinGet packages that are installed system-wide will trigger UAC elevation (fix #3140)
1 parent e1ce380 commit f20c4c1

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativePackageHandler.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
using UniGetUI.Core.Logging;
44
using UniGetUI.PackageEngine.Enums;
55
using UniGetUI.PackageEngine.Interfaces;
6+
using UniGetUI.PackageEngine.PackageClasses;
67

78
namespace UniGetUI.PackageEngine.Managers.WingetManager;
89

910
public static class NativePackageHandler
1011
{
1112
private static readonly ConcurrentDictionary<long, CatalogPackage> __nativePackages = new();
1213
private static readonly ConcurrentDictionary<long, CatalogPackageMetadata> __nativeDetails = new();
13-
private static readonly ConcurrentDictionary<long, PackageInstallerInfo> __nativeInstallers_Install = new();
14+
private static ConcurrentDictionary<long, PackageInstallerInfo> __nativeInstallers_Install = new();
1415
private static ConcurrentDictionary<long, PackageInstallerInfo> __nativeInstallers_Uninstall = new();
1516

1617
/// <summary>
@@ -66,7 +67,7 @@ public static void AddPackage(IPackage package, CatalogPackage catalogPackage)
6667
/// <summary>
6768
/// Get (cached or load) the native installer for the given package, if any. The operation type determines wether
6869
/// </summary>
69-
public static PackageInstallerInfo? GetInstallationOptions(IPackage package, OperationType operation)
70+
public static PackageInstallerInfo? GetInstallationOptions(IPackage package, IInstallationOptions unigetuiOptions, OperationType operation)
7071
// => TaskRecycler<PackageInstallerInfo?>.RunOrAttach(_getInstallationOptions, package, operation);
7172
//
7273
//private static PackageInstallerInfo? _getInstallationOptions(IPackage package, OperationType operation)
@@ -76,22 +77,23 @@ public static void AddPackage(IPackage package, CatalogPackage catalogPackage)
7677

7778
PackageInstallerInfo? installerInfo;
7879
if (operation is OperationType.Uninstall)
79-
installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Uninstall, true);
80+
installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Uninstall, true, unigetuiOptions);
8081
else
81-
installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Uninstall, false);
82+
installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Install, false, unigetuiOptions);
8283

8384
return installerInfo;
8485
}
8586

8687
public static void Clear()
8788
{
88-
__nativePackages.Clear();;
89-
__nativeDetails.Clear();;
90-
__nativeInstallers_Install.Clear();;
89+
__nativePackages.Clear();
90+
__nativeDetails.Clear();
91+
__nativeInstallers_Install.Clear();
9192
__nativeInstallers_Uninstall.Clear();
9293
}
9394

94-
private static PackageInstallerInfo? _getInstallationOptionsOnDict(IPackage package, ref ConcurrentDictionary<long, PackageInstallerInfo> source, bool installed)
95+
private static PackageInstallerInfo? _getInstallationOptionsOnDict(IPackage package,
96+
ref ConcurrentDictionary<long, PackageInstallerInfo> source, bool installed, IInstallationOptions unigetuiOptions)
9597
{
9698
if (source.TryGetValue(package.GetHash(), out PackageInstallerInfo? installerInfo))
9799
return installerInfo;
@@ -100,8 +102,26 @@ public static void Clear()
100102
if (installed) catalogPackage = GetPackage(package)?.InstalledVersion;
101103
else catalogPackage = GetPackage(package)?.DefaultInstallVersion;
102104

103-
InstallOptions? options = NativeWinGetHelper.ExternalFactory?.CreateInstallOptions();
104-
installerInfo = catalogPackage?.GetApplicableInstaller(options);
105+
InstallOptions? wingetOptions = NativeWinGetHelper.ExternalFactory?.CreateInstallOptions();
106+
InstallOptions? wingetDefaultOptions = NativeWinGetHelper.ExternalFactory?.CreateInstallOptions();
107+
108+
if (wingetOptions is null)
109+
{
110+
Logger.Error("WinGetFactory.CreateInstallOptions returned null!");
111+
return installerInfo;
112+
}
113+
114+
if (unigetuiOptions.InstallationScope is PackageScope.Machine)
115+
{
116+
wingetOptions.PackageInstallScope = PackageInstallScope.System;
117+
}
118+
else if (unigetuiOptions.InstallationScope is PackageScope.User)
119+
{
120+
wingetOptions.PackageInstallScope = PackageInstallScope.User;
121+
}
122+
123+
installerInfo = catalogPackage?.GetApplicableInstaller(wingetOptions);
124+
installerInfo ??= catalogPackage?.GetApplicableInstaller(wingetDefaultOptions);
105125

106126
if (installerInfo is not null)
107127
source[package.GetHash()] = installerInfo;

src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ protected override IEnumerable<string> _getOperationParameters(IPackage package,
8989

9090
try
9191
{
92-
var installOptions = NativePackageHandler.GetInstallationOptions(package, operation);
93-
if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationRequired
94-
or ElevationRequirement.ElevatesSelf)
92+
var installOptions = NativePackageHandler.GetInstallationOptions(package, options, operation);
93+
if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationRequired or ElevationRequirement.ElevatesSelf)
9594
{
95+
Logger.Info("Package requires elevation, forcing administrator rights...");
9696
package.OverridenOptions.RunAsAdministrator = true;
9797
}
9898
else if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationProhibited)
@@ -106,11 +106,19 @@ protected override IEnumerable<string> _getOperationParameters(IPackage package,
106106
throw new UnauthorizedAccessException(
107107
CoreTools.Translate("This package cannot be installed from an elevated context.")
108108
+ CoreTools.Translate("Please check the installation options for this package and try again"));
109+
109110
package.OverridenOptions.RunAsAdministrator = false;
110111
}
112+
else if(installOptions?.Scope is PackageInstallerScope.System/* or PackageInstallerScope.Unknown*/)
113+
{
114+
Logger.Info("Package is installed on a system-wide scope, forcing administrator rights...");
115+
package.OverridenOptions.RunAsAdministrator = true;
116+
}
111117
}
112118
catch (Exception ex)
113119
{
120+
if (ex is UnauthorizedAccessException) throw;
121+
114122
Logger.Error("Recovered from fatal WinGet exception:");
115123
Logger.Error(ex);
116124
}

0 commit comments

Comments
 (0)