From f7fa0a688a7ac60eb1712d4acb242b54d8d60040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Thu, 26 Dec 2024 12:36:39 +0100 Subject: [PATCH] Implement Restart method, improve cancel detection on ProcessOperations --- .../AbstractOperation.cs | 8 +++- .../PackageOperations.cs | 4 +- .../ProcessOperation.cs | 16 ++++++-- .../SourceOperations.cs | 8 ++-- .../Helpers/PackagePkgOperationHelper.cs | 40 +++++-------------- .../OperationWidgets/OperationControl.cs | 2 +- 6 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs index ab4718042..90370572a 100644 --- a/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs @@ -99,10 +99,12 @@ public void Cancel() case OperationStatus.Failed: break; case OperationStatus.Running: + Status = OperationStatus.Canceled; CancelRequested?.Invoke(this, EventArgs.Empty); Status = OperationStatus.Canceled; break; case OperationStatus.InQueue: + Status = OperationStatus.Canceled; OperationQueue.Remove(this); Status = OperationStatus.Canceled; break; @@ -195,7 +197,8 @@ public async Task MainThread() { Status = OperationStatus.Failed; OperationFailed?.Invoke(this, EventArgs.Empty); - Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), LineType.StdERR); + Line(Metadata.FailureMessage, LineType.StdERR); + Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), LineType.Progress); } else if (result == OperationVeredict.Canceled) { @@ -214,7 +217,8 @@ public void SkipQueue() public void Retry() { - throw new NotImplementedException(); + if (Status is OperationStatus.Running or OperationStatus.InQueue) return; + _ = MainThread(); } protected abstract Task PerformOperation(); diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs index 524c2ca71..14dd9d202 100644 --- a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -61,7 +61,7 @@ public PackageOperation( bool IgnoreParallelInstalls = false) : this(package, InstallationOptions.FromPackage(package), role, IgnoreParallelInstalls) { } - protected sealed override async Task PrepareProcessStartInfo() + protected sealed override void PrepareProcessStartInfo() { Package.SetTag(PackageTag.OnQueue); string operation_args = string.Join(" ", Package.Manager.OperationHelper.GetParameters(Package, Options, Role)); @@ -74,7 +74,7 @@ protected sealed override async Task PrepareProcessStartInfo() { if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) { - await CoreTools.CacheUACForCurrentProcess(); + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); } process.StartInfo.FileName = CoreData.GSudoPath; diff --git a/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs b/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs index acaa61623..5a2117eeb 100644 --- a/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs @@ -6,11 +6,16 @@ namespace UniGetUI.PackageOperations; public abstract class AbstractProcessOperation : AbstractOperation { protected Process process { get; private set; } + private bool ProcessKilled; protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled) { process = new(); - CancelRequested += (_, _) => process.Kill(); - OperationStarting += async (_, _) => + CancelRequested += (_, _) => + { + ProcessKilled = true; + process.Kill(); + }; + OperationStarting += (_, _) => { process = new(); process.StartInfo.UseShellExecute = false; @@ -50,7 +55,7 @@ protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled) Line(line, lineType); }; - await PrepareProcessStartInfo(); + PrepareProcessStartInfo(); }; } @@ -76,9 +81,12 @@ protected override async Task PerformOperation() Line($"End Time: \"{DateTime.Now}\"", LineType.OperationInfo); Line($"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", LineType.OperationInfo); + if (ProcessKilled) + return OperationVeredict.Canceled; + return await GetProcessVeredict(process.ExitCode, []); } protected abstract Task GetProcessVeredict(int ReturnCode, string[] Output); - protected abstract Task PrepareProcessStartInfo(); + protected abstract void PrepareProcessStartInfo(); } diff --git a/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs index bc9e1090f..aaed5df14 100644 --- a/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs @@ -36,13 +36,13 @@ public class AddSourceOperation : SourceOperation public AddSourceOperation(IManagerSource source) : base(source) { } - protected override async Task PrepareProcessStartInfo() + protected override void PrepareProcessStartInfo() { if (Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) { if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) { - await CoreTools.CacheUACForCurrentProcess(); + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); } process.StartInfo.FileName = CoreData.GSudoPath; process.StartInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); @@ -80,13 +80,13 @@ public class RemoveSourceOperation : SourceOperation public RemoveSourceOperation(IManagerSource source) : base(source) { } - protected override async Task PrepareProcessStartInfo() + protected override void PrepareProcessStartInfo() { if (Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) { if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) { - await CoreTools.CacheUACForCurrentProcess(); + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); } process.StartInfo.FileName = CoreData.GSudoPath; process.StartInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs index 8de4c8591..ea10569a8 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs @@ -30,21 +30,12 @@ public IEnumerable GetParameters( IInstallationOptions options, OperationType operation) { - try - { - var parameters = _getOperationParameters(package, options, operation); - Logger.Info( - $"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + - string.Join(' ', parameters)); - return parameters; - } - catch (Exception ex) - { - Logger.Error( - $"A fatal error ocurred while loading operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}"); - Logger.Error(ex); - return []; - } + var parameters = _getOperationParameters(package, options, operation); + Logger.Info( + $"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + + string.Join(' ', parameters)); + return parameters; + } public OperationVeredict GetResult( @@ -53,22 +44,13 @@ public OperationVeredict GetResult( IEnumerable processOutput, int returnCode) { - try - { - if (returnCode is 999 && processOutput.Last() == "Error: The operation was canceled by the user.") - { - Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); - return OperationVeredict.Canceled; - } - return _getOperationResult(package, operation, processOutput, returnCode); - } - catch (Exception ex) + if (returnCode is 999 && (!processOutput.Any() || processOutput.Last() == "Error: The operation was canceled by the user.")) { - Logger.Error( - $"A fatal error ocurred while loading operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}"); - Logger.Error(ex); - return OperationVeredict.Failure; + Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); + return OperationVeredict.Canceled; } + + return _getOperationResult(package, operation, processOutput, returnCode); } } diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs index fb51de9e1..bfcac7d17 100644 --- a/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs +++ b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs @@ -24,7 +24,7 @@ namespace UniGetUI.Controls.OperationWidgets; public class OperationControl: INotifyPropertyChanged { public AbstractOperation Operation; - private bool ErrorTooltipShown = false; + private bool ErrorTooltipShown; public OperationControl(AbstractOperation operation) {