Skip to content

Commit

Permalink
Fix list refresh crash after Scoop or Steam was uninstalled, or one o…
Browse files Browse the repository at this point in the history
…f BCU's uninstall helper apps was removed
  • Loading branch information
Klocman committed Mar 4, 2023
1 parent 9c7b8a5 commit be95b88
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 127 deletions.
Expand Up @@ -12,7 +12,7 @@ public class GenerateSteamHelperStrings : IMissingInfoAdder
{
public void AddMissingInformation(ApplicationUninstallerEntry target)
{
if (target.UninstallerKind != UninstallerType.Steam || !SteamFactory.SteamHelperIsAvailable) return;
if (target.UninstallerKind != UninstallerType.Steam) return;

var appId = target.RatingId.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Last();
if (!int.TryParse(appId, out _)) return;
Expand Down
17 changes: 3 additions & 14 deletions source/UninstallTools/Factory/OculusFactory.cs
Expand Up @@ -15,24 +15,13 @@ namespace UninstallTools.Factory
{
public class OculusFactory : IIndependantUninstallerFactory
{
private static bool? _helperAvailable;
private static string HelperPath => Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"OculusHelper.exe");

private static bool HelperAvailable
{
get
{
if (!_helperAvailable.HasValue)
_helperAvailable = WindowsTools.CheckNetFramework4Installed(true) != null && File.Exists(HelperPath);

return _helperAvailable.Value;
}
}
private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"OculusHelper.exe");
private static bool IsHelperAvailable() => File.Exists(HelperPath);

public IList<ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (!HelperAvailable) return results;
if (!IsHelperAvailable()) return results;

var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "/query");
if (string.IsNullOrEmpty(output)) return results;
Expand Down
26 changes: 0 additions & 26 deletions source/UninstallTools/Factory/PredefinedFactory.cs
Expand Up @@ -19,35 +19,9 @@ public class PredefinedFactory : IIndependantUninstallerFactory
ListGenerationProgress.ListGenerationCallback progressCallback)
{
var items = new List<ApplicationUninstallerEntry>();

var s = GetSteamUninstallerEntry();
if (s != null)
items.Add(s);

return items;
}

private static ApplicationUninstallerEntry GetSteamUninstallerEntry()
{
if (string.IsNullOrEmpty(SteamFactory.SteamLocation)) return null;

return new ApplicationUninstallerEntry
{
AboutUrl = @"http://store.steampowered.com/about/",
InstallLocation = SteamFactory.SteamLocation,
DisplayIcon = Path.Combine(SteamFactory.SteamLocation, "Steam.exe"),
DisplayName = "Steam",
UninstallerKind = UninstallerType.Nsis,
UninstallString = Path.Combine(SteamFactory.SteamLocation, "uninstall.exe"),
IsOrphaned = true,
IsValid = File.Exists(Path.Combine(SteamFactory.SteamLocation, "uninstall.exe")),
InstallDate = Directory.GetCreationTime(SteamFactory.SteamLocation),
Publisher = "Valve Corporation",
// Prevent very long size scan in case of many games, the install itself is about 600-800MB
EstimatedSize = FileSize.FromKilobytes(1024 * 700)
};
}

public bool IsEnabled() => UninstallToolsGlobalConfig.ScanPreDefined;
public string DisplayName => Localisation.Progress_AppStores_Templates;
}
Expand Down
22 changes: 5 additions & 17 deletions source/UninstallTools/Factory/ScoopFactory.cs
Expand Up @@ -19,7 +19,6 @@ namespace UninstallTools.Factory
{
public sealed partial class ScoopFactory : IIndependantUninstallerFactory
{
private static bool? _scoopIsAvailable;
private static string _scoopUserPath;
private static string _scoopGlobalPath;
private static string _scriptPath;
Expand All @@ -33,20 +32,7 @@ static ScoopFactory()
_jsonContext = new JsonContext(jsonOptions);
}

private static bool ScoopIsAvailable
{
get
{
if (!_scoopIsAvailable.HasValue)
{
_scoopIsAvailable = false;
GetScoopInfo();
}
return _scoopIsAvailable.Value;
}
}

private static void GetScoopInfo()
private static bool GetScoopInfo()
{
try
{
Expand All @@ -66,13 +52,15 @@ private static void GetScoopInfo()
if (!File.Exists(_powershellPath))
throw new InvalidOperationException(@"Detected Scoop program installer, but failed to detect PowerShell");

_scoopIsAvailable = true;
return true;
}
}
catch (SystemException ex)
{
Trace.WriteLine("Failed to get Scoop info: " + ex);
}

return false;
}

private sealed class ExportInfo
Expand Down Expand Up @@ -101,7 +89,7 @@ private sealed class ExportAppEntry
public IList<ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (!ScoopIsAvailable) return results;
if (!GetScoopInfo()) return results;

// Make uninstaller for scoop itself
var scoopEntry = new ApplicationUninstallerEntry
Expand Down
13 changes: 5 additions & 8 deletions source/UninstallTools/Factory/ScriptFactory.cs
Expand Up @@ -17,17 +17,14 @@ namespace UninstallTools.Factory
{
public class ScriptFactory : IIndependantUninstallerFactory
{
private static readonly string ScriptHelperPath;
private static readonly PropertyInfo[] EntryProps;
//private static readonly PropertyInfo[] SystemIconProps;

private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"ScriptHelper.exe");
private static bool IsHelperAvailable() => File.Exists(HelperPath);

static ScriptFactory()
{
var helper = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"ScriptHelper.exe");
var frameworkVersion = WindowsTools.CheckNetFramework4Installed(true);
if (File.Exists(helper) && frameworkVersion != null && frameworkVersion >= new Version(4, 5, 0))
ScriptHelperPath = helper;

EntryProps = typeof(ApplicationUninstallerEntry)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite && p.PropertyType == typeof(string))
Expand All @@ -43,9 +40,9 @@ static ScriptFactory()
ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (ScriptHelperPath == null) return results;
if (!IsHelperAvailable()) return results;

var result = FactoryTools.StartHelperAndReadOutput(ScriptHelperPath, "list");
var result = FactoryTools.StartHelperAndReadOutput(HelperPath, "list");

if (string.IsNullOrEmpty(result)) return results;

Expand Down
61 changes: 25 additions & 36 deletions source/UninstallTools/Factory/SteamFactory.cs
Expand Up @@ -10,7 +10,6 @@
using System.Linq;
using System.Security;
using Klocman.IO;
using Klocman.Tools;
using UninstallTools.Junk;
using UninstallTools.Junk.Confidence;
using UninstallTools.Junk.Containers;
Expand All @@ -20,60 +19,34 @@ namespace UninstallTools.Factory
{
public class SteamFactory : IIndependantUninstallerFactory, IJunkCreator
{
private static bool? _steamHelperIsAvailable;
private static string _steamLocation;

internal static string SteamLocation
{
get
{
if (_steamLocation == null)
GetSteamInfo();
return _steamLocation;
}
private set { _steamLocation = value; }
}

internal static bool SteamHelperIsAvailable
{
get
{
if (!_steamHelperIsAvailable.HasValue)
{
_steamHelperIsAvailable = false;
GetSteamInfo();
}
return _steamHelperIsAvailable.Value;
}
}

private static void GetSteamInfo()
private static bool GetSteamInfo(out string steamLocation)
{
_steamHelperIsAvailable = false;
steamLocation = null;

if (File.Exists(SteamHelperPath) && WindowsTools.CheckNetFramework4Installed(true) != null)
if (File.Exists(SteamHelperPath))
{
var output = FactoryTools.StartHelperAndReadOutput(SteamHelperPath, "steam");
if (!string.IsNullOrEmpty(output)
&& !output.Contains("error", StringComparison.InvariantCultureIgnoreCase)
&& Directory.Exists(output = output.Trim().TrimEnd('\\', '/')))
{
_steamHelperIsAvailable = true;
SteamLocation = output;
steamLocation = output;
return true;
}
}

return false;
}

internal static string SteamHelperPath
=> Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"SteamHelper.exe");
internal static string SteamHelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"SteamHelper.exe");

#region IIndependantUninstallerFactory

public IList<ApplicationUninstallerEntry> GetUninstallerEntries(
ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (!SteamHelperIsAvailable) return results;
if (!GetSteamInfo(out var steamLocation)) return results;

var output = FactoryTools.StartHelperAndReadOutput(SteamHelperPath, "l /i");
if (string.IsNullOrEmpty(output)) return results;
Expand All @@ -99,6 +72,22 @@ internal static string SteamHelperPath
results.Add(entry);
}

results.Add(new ApplicationUninstallerEntry
{
AboutUrl = @"http://store.steampowered.com/about/",
InstallLocation = steamLocation,
DisplayIcon = Path.Combine(steamLocation, "Steam.exe"),
DisplayName = "Steam",
UninstallerKind = UninstallerType.Nsis,
UninstallString = Path.Combine(steamLocation, "uninstall.exe"),
IsOrphaned = true,
IsValid = File.Exists(Path.Combine(steamLocation, "uninstall.exe")),
InstallDate = Directory.GetCreationTime(steamLocation),
Publisher = "Valve Corporation",
// Prevent very long size scan in case of many games, the install itself is about 600-800MB
EstimatedSize = FileSize.FromKilobytes(1024 * 700)
});

return results;
}

Expand Down
16 changes: 5 additions & 11 deletions source/UninstallTools/Factory/StoreAppFactory.cs
Expand Up @@ -17,12 +17,8 @@ namespace UninstallTools.Factory
{
public class StoreAppFactory : IIndependantUninstallerFactory
{
static StoreAppFactory()
{
var storeAppHelperPath = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"StoreAppHelper.exe");
if (WindowsTools.CheckNetFramework4Installed(true) != null && File.Exists(storeAppHelperPath))
StoreAppHelperPath = storeAppHelperPath;
}
private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"StoreAppHelper.exe");
private static bool IsHelperAvailable() => File.Exists(HelperPath);

public static string GetPowerShellRemoveCommand(string fullName)
{
Expand All @@ -39,15 +35,13 @@ public static string[] ToPowerShellRemoveCommands(IEnumerable<ApplicationUninsta
.ToArray();
}

private static string StoreAppHelperPath { get; }

public IList<ApplicationUninstallerEntry> GetUninstallerEntries(
ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (StoreAppHelperPath == null) return results;
if (!IsHelperAvailable()) return results;

var output = FactoryTools.StartHelperAndReadOutput(StoreAppHelperPath, "/query");
var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "/query");
if (string.IsNullOrEmpty(output)) return results;

var windowsPath = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS);
Expand All @@ -57,7 +51,7 @@ public static string[] ToPowerShellRemoveCommands(IEnumerable<ApplicationUninsta
if (!data.ContainsKey("InstalledLocation") || !Directory.Exists(data["InstalledLocation"])) continue;

var fullName = data["FullName"];
var uninstallStr = $"\"{StoreAppHelperPath}\" /uninstall \"{fullName}\"";
var uninstallStr = $"\"{HelperPath}\" /uninstall \"{fullName}\"";
var isProtected = data.ContainsKey("IsProtected") && Convert.ToBoolean(data["IsProtected"], CultureInfo.InvariantCulture);
var result = new ApplicationUninstallerEntry
{
Expand Down
17 changes: 3 additions & 14 deletions source/UninstallTools/Factory/WindowsUpdateFactory.cs
Expand Up @@ -16,24 +16,13 @@ namespace UninstallTools.Factory
{
public class WindowsUpdateFactory : IIndependantUninstallerFactory
{
private static bool? _helperIsAvailable;

private static bool HelperIsAvailable
{
get
{
if (!_helperIsAvailable.HasValue)
_helperIsAvailable = File.Exists(HelperPath) && WindowsTools.CheckNetFramework4Installed(true) != null;
return _helperIsAvailable.Value;
}
}

private static string HelperPath => Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"WinUpdateHelper.exe");
private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"WinUpdateHelper.exe");
private static bool IsHelperAvailable() => File.Exists(HelperPath);

public IList<ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
{
var results = new List<ApplicationUninstallerEntry>();
if (!HelperIsAvailable) return results;
if (!IsHelperAvailable()) return results;

var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "list");
if (string.IsNullOrEmpty(output) || output.Trim().StartsWith("Error", StringComparison.OrdinalIgnoreCase)) return results;
Expand Down

0 comments on commit be95b88

Please sign in to comment.