Install location warning, +reliable uninstalling

This commit is contained in:
pizzaboxer 2023-07-02 23:46:16 +01:00
parent 34b6fef148
commit 7cda363fa7
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
5 changed files with 99 additions and 47 deletions

View File

@ -683,43 +683,68 @@ namespace Bloxstrap
ProtocolHandler.Register("roblox-player", "Roblox", bootstrapperLocation); ProtocolHandler.Register("roblox-player", "Roblox", bootstrapperLocation);
} }
// if the folder we're installed to does not end with "Bloxstrap", we're installed to a user-selected folder
// in which case, chances are they chose to install to somewhere they didn't really mean to (prior to the added warning in 2.4.0)
// if so, we're walking on eggshells and have to ensure we only clean up what we need to clean up
bool cautiousUninstall = !Directories.Base.EndsWith(App.ProjectName);
var cleanupSequence = new List<Action>
{
() => Registry.CurrentUser.DeleteSubKey($@"Software\{App.ProjectName}"),
() => Directory.Delete(Directories.StartMenu, true),
() => File.Delete(Path.Combine(Directories.Desktop, "Play Roblox.lnk")),
() => Registry.CurrentUser.DeleteSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}")
};
if (cautiousUninstall)
{
cleanupSequence.Add(() => Directory.Delete(Directories.Downloads, true));
cleanupSequence.Add(() => Directory.Delete(Directories.Modifications, true));
cleanupSequence.Add(() => Directory.Delete(Directories.Versions, true));
cleanupSequence.Add(() => Directory.Delete(Directories.Logs, true));
cleanupSequence.Add(() => File.Delete(App.Settings.FileLocation));
cleanupSequence.Add(() => File.Delete(App.State.FileLocation));
}
else
{
cleanupSequence.Add(() => Directory.Delete(Directories.Base, true));
}
foreach (var process in cleanupSequence)
{
try try
{ {
// delete application key process();
Registry.CurrentUser.DeleteSubKey($@"Software\{App.ProjectName}");
// delete start menu folder
Directory.Delete(Directories.StartMenu, true);
// delete desktop shortcut
File.Delete(Path.Combine(Directories.Desktop, "Play Roblox.lnk"));
// delete uninstall key
Registry.CurrentUser.DeleteSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}");
// delete installation folder
// (should delete everything except bloxstrap itself)
Directory.Delete(Directories.Base, true);
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"Could not fully uninstall! ({ex})"); App.Logger.WriteLine($"[Bootstrapper::Uninstall] Encountered exception when running cleanup sequence (#{cleanupSequence.IndexOf(process)})");
App.Logger.WriteLine($"[Bootstrapper::Uninstall] {ex}");
}
} }
Action? callback = null; Action? callback = null;
if (Directory.Exists(Directories.Base)) if (Directory.Exists(Directories.Base))
{ {
callback = () => callback = delegate
{ {
// this is definitely one of the workaround hacks of all time // this is definitely one of the workaround hacks of all time
// could antiviruses falsely detect this as malicious behaviour though? // could antiviruses falsely detect this as malicious behaviour though?
// "hmm whats this program doing running a cmd command chain quietly in the background that auto deletes an entire folder" // "hmm whats this program doing running a cmd command chain quietly in the background that auto deletes an entire folder"
string deleteCommand;
if (cautiousUninstall)
deleteCommand = $"del /Q \"{Directories.Application}\"";
else
deleteCommand = $"del /Q \"{Directories.Base}\\*\" && rmdir \"{Directories.Base}\"";
Process.Start(new ProcessStartInfo() Process.Start(new ProcessStartInfo()
{ {
FileName = "cmd.exe", FileName = "cmd.exe",
Arguments = $"/c timeout 5 && del /Q \"{Directories.Base}\\*\" && rmdir \"{Directories.Base}\"", Arguments = $"/c timeout 5 && {deleteCommand}",
UseShellExecute = true, UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden WindowStyle = ProcessWindowStyle.Hidden
}); });

View File

@ -15,23 +15,27 @@ namespace Bloxstrap
public static string Base { get; private set; } = ""; public static string Base { get; private set; } = "";
public static string Downloads { get; private set; } = ""; public static string Downloads { get; private set; } = "";
public static string Logs { get; private set; } = "";
public static string Integrations { get; private set; } = ""; public static string Integrations { get; private set; } = "";
public static string Versions { get; private set; } = ""; public static string Versions { get; private set; } = "";
public static string Modifications { get; private set; } = ""; public static string Modifications { get; private set; } = "";
public static string Application { get; private set; } = ""; public static string Application { get; private set; } = "";
public static bool Initialized => string.IsNullOrEmpty(Base); public static bool Initialized => !String.IsNullOrEmpty(Base);
public static void Initialize(string baseDirectory) public static void Initialize(string baseDirectory)
{ {
Base = baseDirectory; Base = baseDirectory;
Downloads = Path.Combine(Base, "Downloads"); Downloads = Path.Combine(Base, "Downloads");
Logs = Path.Combine(Base, "Logs");
Integrations = Path.Combine(Base, "Integrations"); Integrations = Path.Combine(Base, "Integrations");
Versions = Path.Combine(Base, "Versions"); Versions = Path.Combine(Base, "Versions");
Modifications = Path.Combine(Base, "Modifications"); Modifications = Path.Combine(Base, "Modifications");
Application = Path.Combine(Base, $"{App.ProjectName}.exe"); Application = Path.Combine(Base, $"{App.ProjectName}.exe");
} }
} }
} }

View File

@ -56,9 +56,9 @@ namespace Bloxstrap
FileLocation = location; FileLocation = location;
// clean up any logs older than a week // clean up any logs older than a week
if (!useTempDir) if (Directories.Initialized && Directory.Exists(Directories.Logs))
{ {
foreach (FileInfo log in new DirectoryInfo(directory).GetFiles()) foreach (FileInfo log in new DirectoryInfo(Directories.Logs).GetFiles())
{ {
if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow) if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow)
continue; continue;

View File

@ -69,9 +69,6 @@ namespace Bloxstrap.UI.ViewModels.Menu
if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return; return;
if (!dialog.SelectedPath.EndsWith(App.ProjectName))
InstallLocation = Path.Combine(dialog.SelectedPath, App.ProjectName);
else
InstallLocation = dialog.SelectedPath; InstallLocation = dialog.SelectedPath;
OnPropertyChanged(nameof(InstallLocation)); OnPropertyChanged(nameof(InstallLocation));

View File

@ -10,7 +10,7 @@ using CommunityToolkit.Mvvm.Input;
using Wpf.Ui.Controls.Interfaces; using Wpf.Ui.Controls.Interfaces;
using Wpf.Ui.Mvvm.Contracts; using Wpf.Ui.Mvvm.Contracts;
using Bloxstrap.UI.MessageBox; using System.Linq;
namespace Bloxstrap.UI.ViewModels.Menu namespace Bloxstrap.UI.ViewModels.Menu
{ {
@ -41,6 +41,10 @@ namespace Bloxstrap.UI.ViewModels.Menu
return; return;
} }
bool shouldCheckInstallLocation = App.IsFirstRun || App.BaseDirectory != _originalBaseDirectory;
if (shouldCheckInstallLocation)
{
try try
{ {
// check if we can write to the directory (a bit hacky but eh) // check if we can write to the directory (a bit hacky but eh)
@ -53,7 +57,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
catch (UnauthorizedAccessException) catch (UnauthorizedAccessException)
{ {
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} does not have write access to the install location you selected. Please choose another install location.", $"{App.ProjectName} does not have write access to the install location you've selected. Please choose another location.",
MessageBoxImage.Error MessageBoxImage.Error
); );
return; return;
@ -64,12 +68,34 @@ namespace Bloxstrap.UI.ViewModels.Menu
return; return;
} }
if (!App.BaseDirectory.EndsWith(App.ProjectName) && Directory.Exists(App.BaseDirectory) && Directory.EnumerateFileSystemEntries(App.BaseDirectory).Any())
{
string suggestedChange = Path.Combine(App.BaseDirectory, App.ProjectName);
MessageBoxResult result = Controls.ShowMessageBox(
$"The folder you've chosen to install {App.ProjectName} to already exists and is NOT empty. It is strongly recommended for {App.ProjectName} to be installed to its own independent folder.\n\n" +
"Changing to the following location is suggested:\n" +
$"{suggestedChange}\n\n" +
"Would you like to change your install location to this?\n" +
"Selecting 'No' will ignore this warning and continue installation.",
MessageBoxImage.Warning,
MessageBoxButton.YesNoCancel,
MessageBoxResult.Yes
);
if (result == MessageBoxResult.Yes)
App.BaseDirectory = suggestedChange;
else if (result == MessageBoxResult.Cancel)
return;
}
}
if (!App.IsFirstRun) if (!App.IsFirstRun)
{ {
App.ShouldSaveConfigs = true; App.ShouldSaveConfigs = true;
App.FastFlags.Save(); App.FastFlags.Save();
if (App.BaseDirectory != _originalBaseDirectory) if (shouldCheckInstallLocation)
{ {
App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}"); App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}");