Skip to content

Commit

Permalink
Merge pull request #2824 from marticliment/automatic-winget-troublesh…
Browse files Browse the repository at this point in the history
…ooter

Automated WinGet troubleshooter
  • Loading branch information
marticliment authored Oct 10, 2024
2 parents 7aec68d + d27ed57 commit 1f76a12
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 34 deletions.
13 changes: 12 additions & 1 deletion src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class WinGet : PackageManager
public LocalWinGetSource UbisoftConnectSource { get; }
public LocalWinGetSource GOGSource { get; }
public LocalWinGetSource MicrosoftStoreSource { get; }
public static bool NO_PACKAGES_HAVE_BEEN_LOADED { get; private set; }

public string WinGetBundledPath;

Expand Down Expand Up @@ -96,7 +97,17 @@ protected override IEnumerable<Package> GetAvailableUpdates_UnSafe()

protected override IEnumerable<Package> GetInstalledPackages_UnSafe()
{
return WinGetHelper.Instance.GetInstalledPackages_UnSafe(this);
try
{
var packages = WinGetHelper.Instance.GetInstalledPackages_UnSafe(this);
NO_PACKAGES_HAVE_BEEN_LOADED = !packages.Any();
return packages;
}
catch (Exception)
{
NO_PACKAGES_HAVE_BEEN_LOADED = true;
throw;
}
}

public ManagerSource GetLocalSource(string id)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
using UniGetUI.Core.Classes;
using UniGetUI.Core.Tools;
using UniGetUI.Interface.Enums;
Expand Down Expand Up @@ -40,21 +41,27 @@ public PackageWrapper(IPackage package)

private void Package_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Package.Tag))
try
{
WhenTagHasChanged();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedOpacity)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedComplementaryIconId)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedIconId)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedNameTooltip)));
}
else if (e.PropertyName == nameof(Package.IsChecked))
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsChecked)));
}
else
if (e.PropertyName == nameof(Package.Tag))
{
WhenTagHasChanged();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedOpacity)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedComplementaryIconId)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedIconId)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedNameTooltip)));
}
else if (e.PropertyName == nameof(Package.IsChecked))
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsChecked)));
}
else
{
PropertyChanged?.Invoke(this, e);
}
} catch (COMException)
{
PropertyChanged?.Invoke(this, e);
// ignore
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/UniGetUI/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<RowDefinition Height="36"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0" x:Name="__app_titlebar" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
Expand All @@ -43,8 +44,9 @@
<widgets:TranslatedTextBlock x:Name="AppTitle" Text="WingetUI" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="12"/>
</StackPanel>
</Border>
<InfoBar Name="UpdatesBanner" x:FieldModifier="public" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" IsOpen="False" Visibility="{x:Bind UpdatesBanner.IsOpen, Mode=OneWay}" Margin="0,0,0,4" CornerRadius="0" BorderThickness="0,1,0,1"/>
<InfoBar Name="ErrorBanner" x:FieldModifier="public" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" IsOpen="False" Visibility="{x:Bind ErrorBanner.IsOpen, Mode=OneWay}" Margin="0,0,0,4" Severity="Error" CornerRadius="0" BorderThickness="0,1,0,1"/>
<InfoBar Name="UpdatesBanner" x:FieldModifier="public" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" IsOpen="False" Visibility="{x:Bind UpdatesBanner.IsOpen, Mode=OneWay}" Margin="0,0,0,4" CornerRadius="0" BorderThickness="0,1,0,1"/>
<InfoBar Name="ErrorBanner" x:FieldModifier="public" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" IsOpen="False" Visibility="{x:Bind ErrorBanner.IsOpen, Mode=OneWay}" Margin="0,0,0,4" Severity="Error" CornerRadius="0" BorderThickness="0,1,0,1"/>
<InfoBar Name="WinGetWarningBanner" x:FieldModifier="public" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" IsOpen="False" Visibility="{x:Bind WinGetWarningBanner.IsOpen, Mode=OneWay}" Margin="0,0,0,4" Severity="Warning" CornerRadius="0" BorderThickness="0,1,0,1"/>
</Grid>
<Grid Grid.Row="0" Grid.Column="0" x:Name="LoadingWindow" Visibility="Visible"
Background="{StaticResource ProgressBarBorderThemeBrush}">
Expand Down
22 changes: 19 additions & 3 deletions src/UniGetUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public XamlRoot XamlRoot

public MainView NavigationPage = null!;
public bool BlockLoading;
public readonly TextBlock LoadingSthDalogText;
public readonly ContentDialog LoadingSthDalog;

public int LoadingDialogCount;
Expand Down Expand Up @@ -74,14 +75,30 @@ public MainWindow()
Title = Title + " - DEBUG BUILD";
AppTitle.Text = Title;
#endif
var panel = new StackPanel()
{
Width = 400,
Orientation = Orientation.Vertical,
VerticalAlignment = VerticalAlignment.Stretch,
HorizontalAlignment = HorizontalAlignment.Stretch,
Spacing = 20
};

LoadingSthDalogText = new()
{
HorizontalAlignment = HorizontalAlignment.Stretch, TextWrapping = TextWrapping.Wrap
};

LoadingSthDalog = new ContentDialog
{
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
Title = CoreTools.Translate("Please wait"),
Content = new ProgressBar { IsIndeterminate = true, Width = 300 }
Content = panel
};

panel.Children.Add(LoadingSthDalogText);
panel.Children.Add(new ProgressBar { IsIndeterminate = true, HorizontalAlignment = HorizontalAlignment.Stretch});

foreach (var arg in Environment.GetCommandLineArgs())
{
ParametersToProcess.Enqueue(arg);
Expand Down Expand Up @@ -473,10 +490,9 @@ public void UpdateSystemTrayStatus()
public void SwitchToInterface()
{
SetTitleBar(__app_titlebar);
ContentRoot = ContentRoot;

NavigationPage = new MainView();
Grid.SetRow(NavigationPage, 3);
Grid.SetRow(NavigationPage, 4);
Grid.SetColumn(NavigationPage, 0);
MainContentGrid.Children.Add(NavigationPage);

Expand Down
96 changes: 95 additions & 1 deletion src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System.Diagnostics;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using UniGetUI.Core.Data;
using UniGetUI.Core.Logging;
using UniGetUI.Core.SettingsEngine;
using UniGetUI.Core.Tools;
using UniGetUI.Interface;
using UniGetUI.Interface.Dialogs;
using UniGetUI.PackageEngine;

namespace UniGetUI.Pages.DialogPages;

Expand All @@ -15,10 +18,16 @@ public static partial class DialogHelper
public static MainWindow Window { private get; set; } = null!;

public static void ShowLoadingDialog(string text)
{
ShowLoadingDialog(text, "");
}

public static void ShowLoadingDialog(string title, string description)
{
if (Window.LoadingDialogCount == 0 && Window.DialogQueue.Count == 0)
{
Window.LoadingSthDalog.Title = text;
Window.LoadingSthDalog.Title = title;
Window.LoadingSthDalogText.Text = description;
Window.LoadingSthDalog.XamlRoot = Window.NavigationPage.XamlRoot;
_ = Window.ShowDialogAsync(Window.LoadingSthDalog, HighPriority: true);
}
Expand Down Expand Up @@ -293,5 +302,90 @@ public static async void ShowReleaseNotes()

await Window.ShowDialogAsync(NotesDialog);
}

public static async void HandleBrokenWinGet()
{
try
{
DialogHelper.ShowLoadingDialog("Attempting to repair WinGet...",
"WinGet is being repaired. Please wait until the process finishes.");
Window.WinGetWarningBanner.IsOpen = false;
Process p = new Process()
{
StartInfo = new()
{
FileName =
Path.Join(Environment.SystemDirectory,
"windowspowershell\\v1.0\\powershell.exe"),
Arguments =
"-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {" +
"taskkill /im winget.exe /f; " +
"taskkill /im WindowsPackageManagerServer.exe /f; " +
"Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; " +
"Install-Module Microsoft.WinGet.Client -Force -Scope AllUsers -AllowClobber; " +
"Import-Module Microsoft.WinGet.Client; " +
"Repair-WinGetPackageManager -Force -Latest; " +
"Get-AppxPackage -Name 'Microsoft.DesktopAppInstaller' | Reset-AppxPackage" +
"}\"",
UseShellExecute = true,
Verb = "runas"
}
};
p.Start();
await p.WaitForExitAsync();
DialogHelper.HideLoadingDialog();

// Toggle bundled WinGet
if (Settings.Get("ForceLegacyBundledWinGet"))
Settings.Set("ForceLegacyBundledWinGet", false);

var c = new ContentDialog()
{
Title = CoreTools.Translate("WinGet was repaired successfully"),
Content = CoreTools.Translate("It is recommended to restart UniGetUI after WinGet has been repaired") +
"\n\n" +
CoreTools.Translate(
"NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section"),
PrimaryButtonText = CoreTools.Translate("Restart"),
SecondaryButtonText = CoreTools.Translate("Close"),
DefaultButton = ContentDialogButton.Primary,
XamlRoot = Window.XamlRoot
};

// Restart UniGetUI or reload packages depending on the user's choice
if (await Window.ShowDialogAsync(c) == ContentDialogResult.Primary)
{
MainApp.Instance.KillAndRestart();
}
else
{
_ = PEInterface.UpgradablePackagesLoader.ReloadPackages();
_ = PEInterface.InstalledPackagesLoader.ReloadPackages();
}
}
catch (Exception ex)
{
// Show an error message if something goes wrong
Window.WinGetWarningBanner.IsOpen = true;
Logger.Error("An error occurred while trying to repair WinGet");
Logger.Error(ex);
DialogHelper.HideLoadingDialog();

var c = new ContentDialog()
{
Title = CoreTools.Translate("WinGet could not be repaired"),
Content =
CoreTools.Translate("An unexpected issue occurred while attempting to repair WinGet. Please try again later") +
"\n\n" + ex.Message + "\n\n" +
CoreTools.Translate("NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section"),
PrimaryButtonText = CoreTools.Translate("Close"),
DefaultButton = ContentDialogButton.None,
XamlRoot = Window.XamlRoot
};

await Window.ShowDialogAsync(c);
}

}
}

26 changes: 19 additions & 7 deletions src/UniGetUI/Pages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using UniGetUI.PackageEngine;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.ManagerClasses.Manager;
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.Pages.DialogPages;

// To learn more about WinUI, the WinUI project structure,
Expand Down Expand Up @@ -109,24 +110,35 @@ public SettingsInterface()
ExtraSettingsCards.Add(Manager, []);
}

ButtonCard Winget_ResetSources = new() { Text = CoreTools.AutoTranslated("Reset Winget sources (might help if no packages are listed)"), ButtonText = CoreTools.AutoTranslated("Reset") };
Winget_ResetSources.Click += (_, _) =>
/*ButtonCard WinGet_ResetSources = new() { Text = CoreTools.AutoTranslated("Reset Winget sources (might help if no packages are listed)"), ButtonText = CoreTools.AutoTranslated("Reset") };
WinGet_ResetSources.Click += (_, _) =>
{
CoreTools.LaunchBatchFile(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Utilities", "reset_winget_sources.cmd"), CoreTools.Translate("Resetting Winget sources - WingetUI"), RunAsAdmin: true);
};
};*/

CheckboxCard Winget_UseBundled = new()
CheckboxCard WinGet_UseBundled = new()
{
Text = $"{CoreTools.Translate("Use bundled WinGet instead of system WinGet")} ({CoreTools.Translate("This may help if WinGet packages are not shown")})",
SettingName = "ForceLegacyBundledWinGet"
};
Winget_UseBundled.StateChanged += (_, _) =>
WinGet_UseBundled.StateChanged += (_, _) =>
{
PackageManagerExpanders[PEInterface.WinGet].ShowRestartRequiredBanner();
};

ExtraSettingsCards[PEInterface.WinGet].Add(Winget_UseBundled);
ExtraSettingsCards[PEInterface.WinGet].Add(Winget_ResetSources);
CheckboxCard WinGet_EnableTroubleshooter = new()
{
Text = CoreTools.Translate("Enable the automatic WinGet troubleshooter"),
SettingName = "DisableWinGetMalfunctionDetector"
};
WinGet_EnableTroubleshooter.StateChanged += (_, _) =>
{
MainApp.Instance.MainWindow.WinGetWarningBanner.IsOpen = false;
_ = PEInterface.InstalledPackagesLoader.ReloadPackages();
};

ExtraSettingsCards[PEInterface.WinGet].Add(WinGet_EnableTroubleshooter);
ExtraSettingsCards[PEInterface.WinGet].Add(WinGet_UseBundled);

ButtonCard Scoop_Install = new() { Text = CoreTools.AutoTranslated("Install Scoop"), ButtonText = CoreTools.AutoTranslated("Install") };
Scoop_Install.Click += (_, _) =>
Expand Down
14 changes: 7 additions & 7 deletions src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ private void Loader_PackagesChanged(object? sender, EventArgs e)
}
else
{
foreach (IPackage package in Loader.Packages.ToArray())
foreach (IPackage package in Loader.Packages.ToList())
{
AddPackageToSourcesList(package);
}
Expand Down Expand Up @@ -553,27 +553,27 @@ public void FilterPackages()

if (QueryIdRadio.IsChecked == true)
{
MatchingList = Loader.Packages.Where(x => CharsFunc(x.Name).Contains(treatedQuery));
MatchingList = Loader.Packages.ToArray().Where(x => CharsFunc(x.Name).Contains(treatedQuery));
}
else if (QueryNameRadio.IsChecked == true)
{
MatchingList = Loader.Packages.Where(x => CharsFunc(x.Id).Contains(treatedQuery));
MatchingList = Loader.Packages.ToArray().Where(x => CharsFunc(x.Id).Contains(treatedQuery));
}
else if (QueryBothRadio.IsChecked == true)
{
MatchingList = Loader.Packages.Where(x => CharsFunc(x.Name).Contains(treatedQuery) | CharsFunc(x.Id).Contains(treatedQuery));
MatchingList = Loader.Packages.ToArray().Where(x => CharsFunc(x.Name).Contains(treatedQuery) | CharsFunc(x.Id).Contains(treatedQuery));
}
else if (QueryExactMatch.IsChecked == true)
{
MatchingList = Loader.Packages.Where(x => CharsFunc(x.Name) == treatedQuery | CharsFunc(x.Id) == treatedQuery);
MatchingList = Loader.Packages.ToArray().Where(x => CharsFunc(x.Name) == treatedQuery | CharsFunc(x.Id) == treatedQuery);
}
else // QuerySimilarResultsRadio == true
{
MatchingList = Loader.Packages;
MatchingList = Loader.Packages.ToArray();
}

FilteredPackages.BlockSorting = true;
foreach (IPackage match in MatchingList.ToArray())
foreach (IPackage match in MatchingList)
{
if (VisibleSources.Contains(match.Source) || (!match.Manager.Capabilities.SupportsCustomSources && VisibleManagers.Contains(match.Manager)))
{
Expand Down
13 changes: 13 additions & 0 deletions src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using UniGetUI.Core.Data;
Expand All @@ -9,6 +10,7 @@
using UniGetUI.PackageEngine;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.Managers.WingetManager;
using UniGetUI.PackageEngine.Operations;
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.Pages.DialogPages;
Expand Down Expand Up @@ -275,6 +277,17 @@ protected override void WhenPackagesLoaded(ReloadReason reason)
_ = BackupPackages();
}
}

if(WinGet.NO_PACKAGES_HAVE_BEEN_LOADED && !Settings.Get("DisableWinGetMalfunctionDetector"))
{
var infoBar = MainApp.Instance.MainWindow.WinGetWarningBanner;
infoBar.IsOpen = true;
infoBar.Title = CoreTools.Translate("WinGet malfunction detected");
infoBar.Message = CoreTools.Translate("It looks like WinGet is not working properly. Do you want to attempt to repair WinGet?");
var button = new Button() { Content = CoreTools.Translate("Repair WinGet") };
infoBar.ActionButton = button;
button.Click += (_, _) => DialogHelper.HandleBrokenWinGet();
}
}

protected override void WhenShowingContextMenu(IPackage package)
Expand Down

0 comments on commit 1f76a12

Please sign in to comment.