diff --git a/Source/ChocolateyGui.Shared/ChocolateyGui.Shared.csproj b/Source/ChocolateyGui.Shared/ChocolateyGui.Shared.csproj index c74a1760d..d8774b471 100644 --- a/Source/ChocolateyGui.Shared/ChocolateyGui.Shared.csproj +++ b/Source/ChocolateyGui.Shared/ChocolateyGui.Shared.csproj @@ -30,8 +30,9 @@ 4 - - ..\packages\chocolatey.lib.0.10.6.1\lib\chocolatey.dll + + ..\packages\chocolatey.lib.0.10.7\lib\chocolatey.dll + True ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll diff --git a/Source/ChocolateyGui.Shared/Models/ChocolateySource.cs b/Source/ChocolateyGui.Shared/Models/ChocolateySource.cs index 5d0cddd25..1d44259e2 100644 --- a/Source/ChocolateyGui.Shared/Models/ChocolateySource.cs +++ b/Source/ChocolateyGui.Shared/Models/ChocolateySource.cs @@ -36,6 +36,10 @@ public class ChocolateySource : IEquatable [DataMember] public string CertificatePassword { get; set; } + public bool ByPassProxy { get; set; } + + public bool SelfService { get; set; } + public bool Equals(ChocolateySource other) { if (ReferenceEquals(null, other)) @@ -48,10 +52,16 @@ public bool Equals(ChocolateySource other) return true; } - return string.Equals(Id, other.Id) && string.Equals(Value, other.Value) && Disabled == other.Disabled - && string.Equals(UserName, other.UserName) && string.Equals(Password, other.Password) - && Priority == other.Priority && string.Equals(Certificate, other.Certificate) - && string.Equals(CertificatePassword, other.CertificatePassword); + return string.Equals(Id, other.Id) + && string.Equals(Value, other.Value) + && Disabled == other.Disabled + && string.Equals(UserName, other.UserName) + && string.Equals(Password, other.Password) + && Priority == other.Priority + && string.Equals(Certificate, other.Certificate) + && string.Equals(CertificatePassword, other.CertificatePassword) + && ByPassProxy == other.ByPassProxy + && SelfService == other.SelfService; } public override bool Equals(object obj) @@ -86,6 +96,8 @@ public override int GetHashCode() hashCode = (hashCode * 397) ^ Priority; hashCode = (hashCode * 397) ^ (Certificate?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (CertificatePassword?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ ByPassProxy.GetHashCode(); + hashCode = (hashCode * 397) ^ SelfService.GetHashCode(); return hashCode; } } diff --git a/Source/ChocolateyGui.Shared/packages.config b/Source/ChocolateyGui.Shared/packages.config index 78918a659..d950c82ab 100644 --- a/Source/ChocolateyGui.Shared/packages.config +++ b/Source/ChocolateyGui.Shared/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/Source/ChocolateyGui.Subprocess/ChocolateyGui.Subprocess.csproj b/Source/ChocolateyGui.Subprocess/ChocolateyGui.Subprocess.csproj index 3273b463b..e5727aa8b 100644 --- a/Source/ChocolateyGui.Subprocess/ChocolateyGui.Subprocess.csproj +++ b/Source/ChocolateyGui.Subprocess/ChocolateyGui.Subprocess.csproj @@ -40,8 +40,9 @@ ..\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll - - ..\packages\chocolatey.lib.0.10.6.1\lib\chocolatey.dll + + ..\packages\chocolatey.lib.0.10.7\lib\chocolatey.dll + True ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll diff --git a/Source/ChocolateyGui.Subprocess/ChocolateyService.cs b/Source/ChocolateyGui.Subprocess/ChocolateyService.cs index fd3b3260d..1d89205f3 100644 --- a/Source/ChocolateyGui.Subprocess/ChocolateyService.cs +++ b/Source/ChocolateyGui.Subprocess/ChocolateyService.cs @@ -28,7 +28,7 @@ namespace ChocolateyGui.Subprocess { - [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] + [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = true)] internal class ChocolateyService : IIpcChocolateyService { #pragma warning disable SA1401 // Fields must be private @@ -419,6 +419,8 @@ public async Task AddSource(ChocolateySource source) config.SourceCommand.Certificate = source.Certificate; config.SourceCommand.CertificatePassword = source.CertificatePassword; config.SourceCommand.Priority = source.Priority; + config.SourceCommand.BypassProxy = source.ByPassProxy; + config.SourceCommand.AllowSelfService = source.SelfService; }); await choco.RunAsync(operationContext.GetCancellationToken()); diff --git a/Source/ChocolateyGui.Subprocess/Program.cs b/Source/ChocolateyGui.Subprocess/Program.cs index a59472b9c..5b5d6e784 100644 --- a/Source/ChocolateyGui.Subprocess/Program.cs +++ b/Source/ChocolateyGui.Subprocess/Program.cs @@ -17,7 +17,9 @@ using ILogger = Serilog.ILogger; namespace ChocolateyGui.Subprocess -{ +{ + using chocolatey; + public class Program { public static ManualResetEventSlim CanceledEvent { get; private set; } @@ -48,7 +50,11 @@ public static int Main(string[] args) e.Cancel = true; CanceledEvent.Set(); source.Cancel(); - }; + }; + + // Do not remove! Load Chocolatey once so all config gets set + // properly for future calls + var choco = Lets.GetChocolatey(); CanceledEvent = new ManualResetEventSlim(); diff --git a/Source/ChocolateyGui.Subprocess/packages.config b/Source/ChocolateyGui.Subprocess/packages.config index 5dfc8ac50..91ce9c53b 100644 --- a/Source/ChocolateyGui.Subprocess/packages.config +++ b/Source/ChocolateyGui.Subprocess/packages.config @@ -1,7 +1,7 @@  - + diff --git a/Source/ChocolateyGui/Base/ConnectionClosedException.cs b/Source/ChocolateyGui/Base/ConnectionClosedException.cs new file mode 100644 index 000000000..0c3dee9eb --- /dev/null +++ b/Source/ChocolateyGui/Base/ConnectionClosedException.cs @@ -0,0 +1,15 @@ +// +// Copyright 2014 - Present Rob Reynolds, the maintainers of Chocolatey, and RealDimensions Software, LLC +// + +using System; + +namespace ChocolateyGui.Base +{ + /// + /// Used to represent that a connection closed peacefully while performing operation. Likely means application is closing. + /// + public class ConnectionClosedException : Exception + { + } +} \ No newline at end of file diff --git a/Source/ChocolateyGui/Bootstrapper.cs b/Source/ChocolateyGui/Bootstrapper.cs index 1e0e7fccc..8fa49e5e7 100644 --- a/Source/ChocolateyGui/Bootstrapper.cs +++ b/Source/ChocolateyGui/Bootstrapper.cs @@ -7,12 +7,16 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Reflection; using System.Threading.Tasks; using System.Windows; using Autofac; using Caliburn.Micro; using CefSharp; +using chocolatey; using ChocolateyGui.Properties; +using ChocolateyGui.Services; using ChocolateyGui.Startup; using ChocolateyGui.Utilities; using ChocolateyGui.ViewModels; @@ -89,10 +93,26 @@ protected override void Configure() Internationalization.Initialize(); } - protected override void OnStartup(object sender, StartupEventArgs e) + protected override async void OnStartup(object sender, StartupEventArgs e) { - App.SplashScreen.Close(TimeSpan.FromMilliseconds(300)); - DisplayRootViewFor(); + try + { + var packageSerice = Container.Resolve(); + var features = await packageSerice.GetFeatures(); + + var backgroundFeature = features.FirstOrDefault(feature => string.Equals(feature.Name, "useBackgroundService", StringComparison.OrdinalIgnoreCase)); + var elevationProvider = Elevation.Instance; + elevationProvider.IsBackgroundRunning = backgroundFeature?.Enabled ?? false; + + App.SplashScreen.Close(TimeSpan.FromMilliseconds(300)); + DisplayRootViewFor(); + } + catch (Exception ex) + { + MessageBox.Show($"Failed to start application.\n{ex.Message}\n\nMore details available in application logs."); + Logger.Fatal(ex, "Failed to start application."); + await OnExitAsync(); + } } protected override object GetInstance(Type service, string key) diff --git a/Source/ChocolateyGui/ChocolateyGui.csproj b/Source/ChocolateyGui/ChocolateyGui.csproj index 012a49ad4..290fbd9d4 100644 --- a/Source/ChocolateyGui/ChocolateyGui.csproj +++ b/Source/ChocolateyGui/ChocolateyGui.csproj @@ -60,8 +60,9 @@ ..\packages\Caliburn.Micro.3.1.0\lib\net45\Caliburn.Micro.Platform.Core.dll - - ..\packages\chocolatey.lib.0.10.6.1\lib\chocolatey.dll + + ..\packages\chocolatey.lib.0.10.7\lib\chocolatey.dll + True ..\packages\LiteDB.3.1.0\lib\net35\LiteDB.dll @@ -183,6 +184,7 @@ MSBuild:Compile Designer + InternetImage.xaml @@ -233,7 +235,7 @@ - + diff --git a/Source/ChocolateyGui/Elevation.cs b/Source/ChocolateyGui/Elevation.cs new file mode 100644 index 000000000..e5cade919 --- /dev/null +++ b/Source/ChocolateyGui/Elevation.cs @@ -0,0 +1,62 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright 2014 - Present Rob Reynolds, the maintainers of Chocolatey, and RealDimensions Software, LLC +// +// -------------------------------------------------------------------------------------------------------------------- + +using Autofac; +using Caliburn.Micro; +using ChocolateyGui.Utilities; +using ChocolateyGui.Utilities.Extensions; + +namespace ChocolateyGui +{ + public class Elevation : PropertyChangedBase + { + private bool _isElevated = Hacks.IsElevated; + private bool _isBackgroundRunning = false; + + public static Elevation Instance + { + get { return Bootstrapper.Container.Resolve(); } + } + + public bool IsElevated + { + get + { + return _isElevated; + } + + set + { + this.SetPropertyValue(ref _isElevated, value); + NotifyOfPropertyChange(nameof(CanDoCentralActions)); + } + } + + public bool IsBackgroundRunning + { + get + { + return _isBackgroundRunning; + } + + set + { + this.SetPropertyValue(ref _isBackgroundRunning, value); + NotifyOfPropertyChange(nameof(CanDoCentralActions)); + } + } + + public bool CanDoCentralActions + { + get { return _isBackgroundRunning || _isElevated; } + } + + public bool CanDoTertiaryActions + { + get { return _isElevated; } + } + } +} \ No newline at end of file diff --git a/Source/ChocolateyGui/Properties/Resources.Designer.cs b/Source/ChocolateyGui/Properties/Resources.Designer.cs index f73075ab5..0bf0ed3f2 100644 --- a/Source/ChocolateyGui/Properties/Resources.Designer.cs +++ b/Source/ChocolateyGui/Properties/Resources.Designer.cs @@ -1126,6 +1126,15 @@ public static string SettingsView_Sources { } } + /// + /// Looks up a localized string similar to ByPass Proxy. + /// + public static string SettingsView_SourcesByPassProxy { + get { + return ResourceManager.GetString("SettingsView_SourcesByPassProxy", resourceCulture); + } + } + /// /// Looks up a localized string similar to Certificate. /// @@ -1162,6 +1171,15 @@ public static string SettingsView_SourcesId { } } + /// + /// Looks up a localized string similar to Is Proxy ByPassed. + /// + public static string SettingsView_SourcesIsByPassProxy { + get { + return ResourceManager.GetString("SettingsView_SourcesIsByPassProxy", resourceCulture); + } + } + /// /// Looks up a localized string similar to Is Disabled. /// @@ -1171,6 +1189,15 @@ public static string SettingsView_SourcesIsDisabled { } } + /// + /// Looks up a localized string similar to Is Self Service. + /// + public static string SettingsView_SourcesIsSelfService { + get { + return ResourceManager.GetString("SettingsView_SourcesIsSelfService", resourceCulture); + } + } + /// /// Looks up a localized string similar to Password. /// @@ -1198,6 +1225,15 @@ public static string SettingsView_SourcesPriority { } } + /// + /// Looks up a localized string similar to Self Service. + /// + public static string SettingsView_SourcesSelfService { + get { + return ResourceManager.GetString("SettingsView_SourcesSelfService", resourceCulture); + } + } + /// /// Looks up a localized string similar to Source. /// diff --git a/Source/ChocolateyGui/Properties/Resources.de.resx b/Source/ChocolateyGui/Properties/Resources.de.resx index f3e154882..d1160be91 100644 --- a/Source/ChocolateyGui/Properties/Resources.de.resx +++ b/Source/ChocolateyGui/Properties/Resources.de.resx @@ -165,6 +165,9 @@ Installieren + + Pin + Erneut Installieren @@ -300,6 +303,9 @@ Quellen + + + Zertifikat @@ -321,6 +327,9 @@ Priorität + + + Quelle diff --git a/Source/ChocolateyGui/Properties/Resources.resx b/Source/ChocolateyGui/Properties/Resources.resx index 284d9cf20..8be5dd9ee 100644 --- a/Source/ChocolateyGui/Properties/Resources.resx +++ b/Source/ChocolateyGui/Properties/Resources.resx @@ -576,4 +576,16 @@ NOTE: Probably only necessary to change in RTL languages. Version: {0} + + ByPass Proxy + + + Self Service + + + Is Proxy ByPassed + + + Is Self Service + diff --git a/Source/ChocolateyGui/Properties/Resources.sv.resx b/Source/ChocolateyGui/Properties/Resources.sv.resx index c93dd8699..62f352563 100644 --- a/Source/ChocolateyGui/Properties/Resources.sv.resx +++ b/Source/ChocolateyGui/Properties/Resources.sv.resx @@ -519,6 +519,9 @@ NOTE: Probably only necessary to change in RTL languages. Källor + + + Certifikat @@ -543,6 +546,9 @@ NOTE: Probably only necessary to change in RTL languages. Prioritet + + + Källa diff --git a/Source/ChocolateyGui/Resources/Controls.xaml b/Source/ChocolateyGui/Resources/Controls.xaml index 5e13be5bc..19f0b9bf0 100644 --- a/Source/ChocolateyGui/Resources/Controls.xaml +++ b/Source/ChocolateyGui/Resources/Controls.xaml @@ -8,7 +8,7 @@ xmlns:converters="clr-namespace:ChocolateyGui.Utilities.Converters" xmlns:commands="clr-namespace:ChocolateyGui.Commands" xmlns:utilities="clr-namespace:ChocolateyGui.Utilities" - xmlns:providers="clr-namespace:ChocolateyGui.Providers" + xmlns:app="clr-namespace:ChocolateyGui" xmlns:lang="clr-namespace:ChocolateyGui.Properties" mc:Ignorable="d"> @@ -23,17 +23,33 @@ - + - - - - - + + + + + + + + + + + + + 15 @@ -649,10 +665,10 @@ - - @@ -661,7 +677,7 @@ - @@ -670,13 +686,13 @@ - - - diff --git a/Source/ChocolateyGui/Services/ChocolateyRemotePackageService.cs b/Source/ChocolateyGui/Services/ChocolateyRemotePackageService.cs index 7e336f725..4cc69147c 100644 --- a/Source/ChocolateyGui/Services/ChocolateyRemotePackageService.cs +++ b/Source/ChocolateyGui/Services/ChocolateyRemotePackageService.cs @@ -40,7 +40,7 @@ public class ChocolateyRemotePackageService : IChocolateyPackageService, IDispos private Process _chocolateyProcess; private IIpcChocolateyService _chocolateyService; - private bool? _requiresElevation; + private bool? _canBeElevated; public ChocolateyRemotePackageService( IProgressService progressService, @@ -61,12 +61,12 @@ public async Task Search(string query, PackageSearchOption await Initialize(); var results = await _chocolateyService.Search(query, options); return new PackageSearchResults - { - Packages = + { + Packages = results.Packages.Select( pcgke => _mapper.Map(pcgke, _packageFactory())), - TotalCount = results.TotalCount - }; + TotalCount = results.TotalCount + }; } public async Task GetByVersionAndIdAsync(string id, SemanticVersion version, bool isPrerelease) @@ -95,6 +95,11 @@ public async Task>> GetOutdatedPack public async Task InstallPackage(string id, SemanticVersion version = null, Uri source = null, bool force = false) { await Initialize(true); + if (Elevation.Instance.IsBackgroundRunning) + { + source = null; + } + var result = await _chocolateyService.InstallPackage(id, version?.ToString(), source, force); if (!result.Successful) { @@ -145,6 +150,11 @@ await _progressService.ShowMessageAsync( public async Task UpdatePackage(string id, Uri source = null) { await Initialize(true); + if (Elevation.Instance.IsBackgroundRunning) + { + source = null; + } + var result = await _chocolateyService.UpdatePackage(id, source); if (!result.Successful) { @@ -226,6 +236,10 @@ public async Task SetFeature(ChocolateyFeature feature) { await Initialize(true); await _chocolateyService.SetFeature(feature); + if (string.Equals(feature.Name, "useBackgroundService", StringComparison.OrdinalIgnoreCase)) + { + Elevation.Instance.IsBackgroundRunning = feature.Enabled; + } } public async Task> GetSettings() @@ -264,9 +278,9 @@ public async Task RemoveSource(string id) return await _chocolateyService.RemoveSource(id); } - public ValueTask RequiresElevation() + public ValueTask CanBeElevated() { - return _requiresElevation.HasValue ? new ValueTask(_requiresElevation.Value) : new ValueTask(RequiresElevationImpl()); + return _canBeElevated.HasValue ? new ValueTask(_canBeElevated.Value) : new ValueTask(CanBeElevatedImpl()); } public void Dispose() @@ -280,11 +294,15 @@ public void Dispose() } } - private async Task RequiresElevationImpl() + private async Task CanBeElevatedImpl() { - await Initialize(); - _requiresElevation = !await _chocolateyService.IsElevated(); - return _requiresElevation.Value; + if (_chocolateyProcess == null || _chocolateyProcess.HasExited) + { + await Initialize(); + } + + _canBeElevated = !Elevation.Instance.IsBackgroundRunning && !await _chocolateyService.IsElevated(); + return _canBeElevated.Value; } private async Task Initialize(bool requireAdmin = false) @@ -307,7 +325,7 @@ private async Task InitializeImpl(bool requireAdmin = false) // Check if we're not already initialized or running, as well as our permissions level. if (_chocolateyProcess != null && !_chocolateyProcess.HasExited) { - if (!requireAdmin || await _chocolateyService.IsElevated()) + if (!requireAdmin || !await CanBeElevated()) { return; } @@ -318,7 +336,7 @@ private async Task InitializeImpl(bool requireAdmin = false) // Double check our initialization and permissions status. if (_chocolateyProcess != null && !_chocolateyProcess.HasExited) { - if (!requireAdmin || await _chocolateyService.IsElevated()) + if (!requireAdmin || !await CanBeElevated()) { return; } @@ -380,7 +398,8 @@ private async Task InitializeImpl(bool requireAdmin = false) _chocolateyService = CreateClient(); // ReSharper disable once PossibleNullReferenceException - ((ElevationStatusProvider)Application.Current.FindResource("Elevation")).IsElevated = await _chocolateyService.IsElevated(); + Elevation.Instance.IsElevated = await _chocolateyService.IsElevated(); + _canBeElevated = !Elevation.Instance.IsBackgroundRunning && !Elevation.Instance.IsElevated; } } diff --git a/Source/ChocolateyGui/Services/IChocolateyPackageService.cs b/Source/ChocolateyGui/Services/IChocolateyPackageService.cs index 66d43c9e8..ac33a741e 100644 --- a/Source/ChocolateyGui/Services/IChocolateyPackageService.cs +++ b/Source/ChocolateyGui/Services/IChocolateyPackageService.cs @@ -38,7 +38,7 @@ public interface IChocolateyPackageService Task SetFeature(ChocolateyFeature feature); - ValueTask RequiresElevation(); + ValueTask CanBeElevated(); Task> GetSettings(); diff --git a/Source/ChocolateyGui/Startup/ChocolateyGuiModule.cs b/Source/ChocolateyGui/Startup/ChocolateyGuiModule.cs index ed6fcabb4..197a4fa37 100644 --- a/Source/ChocolateyGui/Startup/ChocolateyGuiModule.cs +++ b/Source/ChocolateyGui/Startup/ChocolateyGuiModule.cs @@ -31,6 +31,7 @@ protected override void Load(ContainerBuilder builder) // Register Providers builder.RegisterType().As().SingleInstance(); + builder.RegisterType().SingleInstance(); var configurationProvider = new ChocolateyConfigurationProvider(); builder.RegisterInstance(configurationProvider).As().SingleInstance(); diff --git a/Source/ChocolateyGui/ViewModels/LocalSourceViewModel.cs b/Source/ChocolateyGui/ViewModels/LocalSourceViewModel.cs index a5d28881d..302f8d934 100644 --- a/Source/ChocolateyGui/ViewModels/LocalSourceViewModel.cs +++ b/Source/ChocolateyGui/ViewModels/LocalSourceViewModel.cs @@ -20,6 +20,7 @@ using ChocolateyGui.Utilities.Extensions; using ChocolateyGui.ViewModels.Items; using Serilog; +using ChocolateyGui.Base; namespace ChocolateyGui.ViewModels { @@ -305,6 +306,10 @@ private async Task LoadPackages() await _eventAggregator.PublishOnUIThreadAsync(new PackageHasUpdateMessage(update.Item1, update.Item2)); } } + catch (ConnectionClosedException) + { + Logger.Warning("Threw connection closed message while processing load packages."); + } catch (Exception ex) { Logger.Fatal("Packages failed to load", ex); diff --git a/Source/ChocolateyGui/Views/PackageView.xaml b/Source/ChocolateyGui/Views/PackageView.xaml index 161b2f5c1..547e452e0 100644 --- a/Source/ChocolateyGui/Views/PackageView.xaml +++ b/Source/ChocolateyGui/Views/PackageView.xaml @@ -8,7 +8,7 @@ xmlns:commands="clr-namespace:ChocolateyGui.Commands" xmlns:viewModels="clr-namespace:ChocolateyGui.ViewModels" xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks" - xmlns:controls="clr-namespace:ChocolateyGui.Controls" + xmlns:controls="clr-namespace:ChocolateyGui.Controls" xmlns:lang="clr-namespace:ChocolateyGui.Properties" mc:Ignorable="d" d:DesignHeight="786" d:DesignWidth="1366" @@ -19,7 +19,13 @@ - + - + - + - + - + - + + + + - + - + - - + + + + + - +