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
Expand Up @@ -16,6 +16,10 @@
using UniGetUI.PackageEngine.Operations;
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.PackageEngine.PackageLoader;
using UniGetUI.PackageOperations;
#if WINDOWS
using UniGetUI.PackageEngine.Managers.WingetManager;
#endif

namespace UniGetUI.Avalonia.Infrastructure;

Expand Down Expand Up @@ -81,6 +85,14 @@ public static async Task AskLocationAndDownloadAsync(IPackage? package, TEL_Inst
if (package is null) return;
if (MainWindow.Instance is not { } win) return;

#if WINDOWS
if (package.Manager is WinGet && Settings.Get(Settings.K.WinGetDownloadFullManifest))
{
await AskFolderAndDownloadWinGetManifestAsync(package, referral, win);
return;
}
#endif

await package.Details.Load();

if (package.Details.InstallerUrl is null)
Expand Down Expand Up @@ -141,16 +153,45 @@ public static async Task DownloadSelectedAsync(IEnumerable<IPackage> packages, T
var outputPath = folder?.TryGetLocalPath();
if (outputPath is null) return;

bool fullManifest = Settings.Get(Settings.K.WinGetDownloadFullManifest);
foreach (var pkg in eligible)
{
var op = new DownloadOperation(pkg, outputPath);
AbstractOperation op;
#if WINDOWS
if (fullManifest && pkg.Manager is WinGet)
op = new WinGetManifestDownloadOperation(pkg, outputPath);
else
op = new DownloadOperation(pkg, outputPath);
#else
op = new DownloadOperation(pkg, outputPath);
#endif
op.OperationSucceeded += (_, _) => TelemetryHandler.DownloadPackage(pkg, TEL_OP_RESULT.SUCCESS, referral);
op.OperationFailed += (_, _) => TelemetryHandler.DownloadPackage(pkg, TEL_OP_RESULT.FAILED, referral);
AvaloniaOperationRegistry.Add(op);
_ = op.MainThread();
}
}

#if WINDOWS
private static async Task AskFolderAndDownloadWinGetManifestAsync(
IPackage package,
TEL_InstallReferral referral,
MainWindow win)
{
var folders = await win.StorageProvider.OpenFolderPickerAsync(
new FolderPickerOpenOptions { AllowMultiple = false });
var folder = folders.FirstOrDefault();
var outputPath = folder?.TryGetLocalPath();
if (outputPath is null) return;

var op = new WinGetManifestDownloadOperation(package, outputPath);
op.OperationSucceeded += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral);
op.OperationFailed += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral);
AvaloniaOperationRegistry.Add(op);
_ = op.MainThread();
}
#endif

/// <summary>
/// Runs the WinGet self-repair sequence elevated and shows a result notification.
/// Only meaningful on Windows; no-ops on other platforms.
Expand Down
2 changes: 1 addition & 1 deletion src/UniGetUI.Avalonia/UniGetUI.Avalonia.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<PackageReference Include="Octokit" Version="14.0.0" />
<PackageReference Include="Avalonia.Controls.WebView" Version="12.0.0" />
<PackageReference Include="Tmds.DBus.Protocol" Version="0.92.0" />
<PackageReference Include="Devolutions.Pinget.Cli.Rust" Version="0.7.0" GeneratePathProperty="true" ExcludeAssets="build;buildTransitive;native" />
<PackageReference Include="Devolutions.Pinget.Cli.Rust" Version="0.8.1" GeneratePathProperty="true" ExcludeAssets="build;buildTransitive;native" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,14 @@ private void BuildExtraControls(CheckboxCard_Dict disableNotifsCard)
{
Text = CoreTools.Translate("Force install location parameter when updating packages with custom locations"),
SettingName = CoreSettings.K.WinGetForceLocationOnUpdate,
CornerRadius = new CornerRadius(0),
BorderThickness = new Thickness(1, 0, 1, 1),
});

ExtraControls.Children.Add(new CheckboxCard
{
Text = CoreTools.Translate("Download full package manifest alongside the installer"),
SettingName = CoreSettings.K.WinGetDownloadFullManifest,
CornerRadius = new CornerRadius(0, 0, 8, 8),
BorderThickness = new Thickness(1, 0, 1, 1),
});
Expand Down
2 changes: 2 additions & 0 deletions src/UniGetUI.Core.Settings/SettingsEngine_Names.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public enum K
PerManagerMinimumUpdateAgeCustom,
WinGetCliToolPreference,
WinGetComApiPolicy,
WinGetDownloadFullManifest,
DisableClassicMode,
DisableInstallerHostChangeWarning,
BunPreferLatestVersions,
Expand Down Expand Up @@ -192,6 +193,7 @@ public static string ResolveKey(K key)
K.PerManagerMinimumUpdateAgeCustom => "PerManagerMinimumUpdateAgeCustom",
K.WinGetCliToolPreference => "WinGetCliToolPreference",
K.WinGetComApiPolicy => "WinGetComApiPolicy",
K.WinGetDownloadFullManifest => "WinGetDownloadFullManifest",
K.DisableClassicMode => "DisableClassicMode",
K.DisableInstallerHostChangeWarning => "DisableInstallerHostChangeWarning",
K.BunPreferLatestVersions => "BunPreferLatestVersions",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("UniGetUI.PackageEngine.Tests")]
[assembly: InternalsVisibleTo("UniGetUI.PackageEngine.Operations")]
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Devolutions.Pinget.Core" Version="0.7.0" />
<PackageReference Include="Devolutions.Pinget.Core" Version="0.8.1" />
<PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#if WINDOWS
using UniGetUI.Core.Tools;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.Managers.WingetManager;
using UniGetUI.PackageOperations;

namespace UniGetUI.PackageEngine.Operations;

public class WinGetManifestDownloadOperation : AbstractProcessOperation
{
private readonly IPackage _package;
private readonly string _downloadDirectory;
public IPackage Package => _package;
public string DownloadLocation => _downloadDirectory;

public WinGetManifestDownloadOperation(IPackage package, string downloadDirectory)
: base(true, null)
{
_package = package;
_downloadDirectory = downloadDirectory;

Metadata.OperationInformation =
"Downloading installer and manifest for WinGet Package="
+ _package.Id
+ " into "
+ _downloadDirectory;
Metadata.Title = CoreTools.Translate(
"{package} installer and manifest download",
new Dictionary<string, object?> { { "package", _package.Name } }
);
Metadata.Status = CoreTools.Translate(
"{0} installer and manifest are being downloaded",
_package.Name
);
Metadata.SuccessTitle = CoreTools.Translate("Download succeeded");
Metadata.SuccessMessage = CoreTools.Translate(
"{package} installer and manifest were downloaded successfully",
new Dictionary<string, object?> { { "package", _package.Name } }
);
Metadata.FailureTitle = CoreTools.Translate(
"Download failed",
new Dictionary<string, object?> { { "package", _package.Name } }
);
Metadata.FailureMessage = CoreTools.Translate(
"{package} installer and manifest could not be downloaded",
new Dictionary<string, object?> { { "package", _package.Name } }
);
}

public override Task<Uri> GetOperationIcon()
{
return Task.Run(_package.GetIconUrl);
}

protected override void ApplyRetryAction(string retryMode)
{
// Do nothing
}

protected override void PrepareProcessStartInfo()
{
var winget = (WinGet)_package.Manager;
bool usePinget = winget.SelectedCliToolKind == WinGetCliToolKind.BundledPinget;

List<string> args = ["download"];

args.AddRange(WinGetPkgOperationHelper.GetIdNamePiece(_package).Split(" "));

if (!_package.Source.IsVirtualManager)
{
args.AddRange(["--source", _package.Source.Name]);
}

args.AddRange(["--download-directory", $"\"{_downloadDirectory}\""]);

if (!usePinget)
{
args.AddRange(
[
"--accept-package-agreements",
"--accept-source-agreements",
"--disable-interactivity",
]
);

string proxyArg = WinGet.GetProxyArgument();
if (proxyArg.Length > 0)
{
args.AddRange(proxyArg.Split(' '));
}
}

process.StartInfo.FileName = winget.Status.ExecutablePath;
process.StartInfo.Arguments =
winget.Status.ExecutableCallArgs + " " + string.Join(" ", args);
}

protected override Task<OperationVeredict> GetProcessVeredict(
int ReturnCode,
List<string> Output
)
{
// winget download return codes follow the standard winget code space.
uint uintCode = (uint)ReturnCode;

if (uintCode is 0x8A150077 or 0x8A15010C or 0x8A150005)
return Task.FromResult(OperationVeredict.Canceled);

return Task.FromResult(
ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure
);
}
}
#endif
49 changes: 48 additions & 1 deletion src/UniGetUI/AppOperationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.UI.Xaml.Controls;
using UniGetUI.Controls.OperationWidgets;
using UniGetUI.Core.Logging;
using UniGetUI.Core.SettingsEngine;
using UniGetUI.Core.Tools;
using UniGetUI.Interface;
using UniGetUI.Interface.Enums;
Expand All @@ -11,6 +12,7 @@
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.Managers.PowerShellManager;
using UniGetUI.PackageEngine.Managers.WingetManager;
using UniGetUI.PackageEngine.Operations;
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.PackageEngine.PackageLoader;
Expand Down Expand Up @@ -65,6 +67,15 @@ TEL_InstallReferral referral
{
if (package is null)
return null;

if (
package.Manager is WinGet
&& Settings.Get(Settings.K.WinGetDownloadFullManifest)
)
{
return await AskFolderAndDownloadWinGetManifest(package, referral);
}

int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait..."));
try
{
Expand Down Expand Up @@ -152,6 +163,38 @@ TEL_InstallReferral referral
}
}

private static async Task<AbstractOperation?> AskFolderAndDownloadWinGetManifest(
IPackage package,
TEL_InstallReferral referral
)
{
try
{
var hWnd = Instance.MainWindow.GetWindowHandle();
var picker = new ExternalLibraries.Pickers.FolderPicker(hWnd);
var outputPath = await Task.Run(picker.Show);
if (string.IsNullOrEmpty(outputPath))
return null;

var op = new WinGetManifestDownloadOperation(package, outputPath);
op.OperationSucceeded += (_, _) =>
TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral);
op.OperationFailed += (_, _) =>
TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral);
Add(op);
Instance.MainWindow.UpdateSystemTrayStatus();
return op;
}
catch (Exception ex)
{
Logger.Error(
$"An error occurred while downloading the WinGet manifest for package {package.Id}"
);
Logger.Error(ex);
return null;
}
}

public static async Task Download(
IEnumerable<IPackage> packages,
TEL_InstallReferral referral
Expand All @@ -168,6 +211,7 @@ TEL_InstallReferral referral
if (outputPath == "")
return;

bool fullManifest = Settings.Get(Settings.K.WinGetDownloadFullManifest);
foreach (var package in packages)
{
if (
Expand All @@ -179,7 +223,10 @@ TEL_InstallReferral referral
continue;
}

var op = new DownloadOperation(package, outputPath);
AbstractOperation op =
fullManifest && package.Manager is WinGet
? new WinGetManifestDownloadOperation(package, outputPath)
: new DownloadOperation(package, outputPath);
op.OperationSucceeded += (_, _) =>
TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral);
op.OperationFailed += (_, _) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
};
ExtraControls.Children.Add(WinGet_ForceLocationWhenUpdating);

CheckboxCard WinGet_DownloadFullManifest = new()
{
Text = CoreTools.Translate(
"Download full package manifest alongside the installer"
),
SettingName = Settings.K.WinGetDownloadFullManifest,
CornerRadius = new CornerRadius(0),
BorderThickness = new Thickness(1, 0, 1, 1),
};
ExtraControls.Children.Add(WinGet_DownloadFullManifest);

CheckboxCard WinGet_EnableTroubleshooter = new()
{
Text = CoreTools.Translate("Enable the automatic WinGet troubleshooter"),
Expand Down
2 changes: 1 addition & 1 deletion src/UniGetUI/UniGetUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageReference Include="Octokit" Version="14.0.0" />
<PackageReference Include="Devolutions.UniGetUI.Elevator" Version="2.6.1.3" GeneratePathProperty="true" ExcludeAssets="build;buildTransitive;native" />
<PackageReference Include="Devolutions.Pinget.Cli.Rust" Version="0.7.0" GeneratePathProperty="true" ExcludeAssets="build;buildTransitive;native" />
<PackageReference Include="Devolutions.Pinget.Cli.Rust" Version="0.8.1" GeneratePathProperty="true" ExcludeAssets="build;buildTransitive;native" />

<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
Expand Down
Loading