Improve install migrating

All Bloxstrap files are now copied instead of just the Bloxstrap executable
This commit is contained in:
pizzaboxer 2023-02-17 19:05:10 +00:00
parent e075e9b847
commit 1166ef9d60
6 changed files with 101 additions and 66 deletions

View File

@ -27,6 +27,7 @@ namespace Bloxstrap
public const string ProjectName = "Bloxstrap";
public const string ProjectRepository = "pizzaboxer/bloxstrap";
// used only for communicating between app and menu - use Directories.Base for anything else
public static string BaseDirectory = null!;
public static bool ShouldSaveConfigs { get; set; } = false;
public static bool IsSetupComplete { get; set; } = true;

View File

@ -67,6 +67,7 @@ namespace Bloxstrap
private readonly CancellationTokenSource _cancelTokenSource = new();
private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid);
private static string DesktopShortcutLocation => Path.Combine(Directories.Desktop, "Play Roblox.lnk");
private string? _launchCommandLine;
@ -114,6 +115,8 @@ namespace Bloxstrap
await CheckLatestVersion();
CheckInstallMigration();
// if bloxstrap is installing for the first time but is running, prompt to close roblox
// if roblox needs updating but is running, ignore update for now
if (!Directory.Exists(_versionFolder) && CheckIfRunning(true) || App.State.Prop.VersionGuid != _versionGuid && !CheckIfRunning(false))
@ -199,6 +202,69 @@ namespace Bloxstrap
_versionPackageManifest = await PackageManifest.Get(_versionGuid);
}
private void CheckInstallMigration()
{
// check if we've changed our install location since the last time we started
// in which case, we'll have to copy over all our folders so we don't lose any mods and stuff
using RegistryKey? applicationKey = Registry.CurrentUser.OpenSubKey($@"Software\{App.ProjectName}", true);
string? oldInstallLocation = (string?)applicationKey?.GetValue("OldInstallLocation");
if (applicationKey is null || oldInstallLocation is null || oldInstallLocation == Directories.Base)
return;
SetStatus("Migrating install location...");
if (Directory.Exists(oldInstallLocation))
{
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Moving all files in {oldInstallLocation} to {Directories.Base}...");
foreach (string oldFileLocation in Directory.GetFiles(oldInstallLocation, "*.*", SearchOption.AllDirectories))
{
string relativeFile = oldFileLocation.Substring(oldInstallLocation.Length + 1);
string newFileLocation = Path.Combine(Directories.Base, relativeFile);
string? newDirectory = Path.GetDirectoryName(newFileLocation);
try
{
if (!String.IsNullOrEmpty(newDirectory))
Directory.CreateDirectory(newDirectory);
File.Move(oldFileLocation, newFileLocation, true);
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to move {oldFileLocation} to {newFileLocation}! {ex}");
}
}
try
{
Directory.Delete(oldInstallLocation, true);
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Deleted old install location");
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to delete old install location! {ex}");
}
}
applicationKey.DeleteValue("OldInstallLocation");
// allow shortcuts to be re-registered
if (Directory.Exists(Directories.StartMenu))
Directory.Delete(Directories.StartMenu, true);
if (File.Exists(DesktopShortcutLocation))
{
File.Delete(DesktopShortcutLocation);
App.Settings.Prop.CreateDesktopIcon = true;
}
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Finished migrating install location!");
}
private bool CheckIfRunning(bool shutdown)
{
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Checking if Roblox is running... (shutdown={shutdown})");
@ -393,30 +459,14 @@ namespace Bloxstrap
#region App Install
public static void Register()
{
RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}");
// new install location selected, delete old one
string? oldInstallLocation = (string?)applicationKey.GetValue("OldInstallLocation");
if (!String.IsNullOrEmpty(oldInstallLocation) && oldInstallLocation != Directories.Base)
using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
{
try
{
if (Directory.Exists(oldInstallLocation))
Directory.Delete(oldInstallLocation, true);
}
catch (Exception)
{
// ignored
}
applicationKey.DeleteValue("OldInstallLocation");
}
applicationKey.SetValue("InstallLocation", Directories.Base);
applicationKey.Close();
}
// set uninstall key
RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}");
using (RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}"))
{
uninstallKey.SetValue("DisplayIcon", $"{Directories.Application},0");
uninstallKey.SetValue("DisplayName", App.ProjectName);
uninstallKey.SetValue("DisplayVersion", App.Version);
@ -432,9 +482,9 @@ namespace Bloxstrap
uninstallKey.SetValue("UninstallString", $"\"{Directories.Application}\" -uninstall");
uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}");
uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest");
uninstallKey.Close();
}
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application version");
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application");
}
public static void CheckInstall()
@ -485,10 +535,10 @@ namespace Bloxstrap
if (App.Settings.Prop.CreateDesktopIcon)
{
if (!File.Exists(Path.Combine(Directories.Desktop, "Play Roblox.lnk")))
if (!File.Exists(DesktopShortcutLocation))
{
ShellLink.Shortcut.CreateShortcut(Directories.Application, "", Directories.Application, 0)
.WriteToFile(Path.Combine(Directories.Desktop, "Play Roblox.lnk"));
.WriteToFile(DesktopShortcutLocation);
}
// one-time toggle, set it back to false

View File

@ -41,7 +41,7 @@ namespace Bloxstrap.Helpers.Integrations
if (process.MainModule?.FileName is null)
continue;
if (!process.MainModule.FileName.Contains(App.BaseDirectory))
if (!process.MainModule.FileName.Contains(Directories.Base))
continue;
process.Kill();
@ -56,7 +56,7 @@ namespace Bloxstrap.Helpers.Integrations
public static async Task CheckInstall()
{
string folderLocation = Path.Combine(App.BaseDirectory, "Integrations\\rbxfpsunlocker");
string folderLocation = Path.Combine(Directories.Base, "Integrations\\rbxfpsunlocker");
string fileLocation = Path.Combine(folderLocation, "rbxfpsunlocker.exe");
string settingsLocation = Path.Combine(folderLocation, "settings");

View File

@ -15,7 +15,7 @@ namespace Bloxstrap.Helpers
{
public class JsonManager<T> where T : new()
{
public T Prop { get; set; } = new T();
public T Prop { get; set; } = new();
//public bool ShouldSave { get; set; } = true;
public string FileLocation => Path.Combine(Directories.Base, $"{typeof(T).Name}.json");
//public string? FileLocation { get; set; } = null;

View File

@ -2,6 +2,7 @@
using System.IO;
using System.Windows;
using System.Windows.Input;
using Bloxstrap.Helpers;
using Microsoft.Win32;
using CommunityToolkit.Mvvm.Input;
using Wpf.Ui.Controls.Interfaces;
@ -39,19 +40,11 @@ namespace Bloxstrap.ViewModels
try
{
// check if we can write to the directory (a bit hacky but eh)
string testFile = Path.Combine(App.BaseDirectory, $"{App.ProjectName}WriteTest.txt");
string testPath = App.BaseDirectory;
string testFile = Path.Combine(testPath, $"{App.ProjectName}WriteTest.txt");
bool testPathExists = Directory.Exists(testPath);
if (!testPathExists)
Directory.CreateDirectory(testPath);
Directory.CreateDirectory(App.BaseDirectory);
File.WriteAllText(testFile, "hi");
File.Delete(testFile);
if (!testPathExists)
Directory.Delete(testPath);
}
catch (UnauthorizedAccessException)
{
@ -71,22 +64,13 @@ namespace Bloxstrap.ViewModels
if (App.BaseDirectory != _originalBaseDirectory)
{
App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}");
App.ShowMessageBox($"{App.ProjectName} will install to the new location you've set the next time it runs.", MessageBoxImage.Information);
App.State.Prop.VersionGuid = "";
using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
{
using RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}");
registryKey.SetValue("InstallLocation", App.BaseDirectory);
registryKey.SetValue("OldInstallLocation", _originalBaseDirectory);
registryKey.Close();
}
// preserve settings
// we don't need to copy the bootstrapper over since the install process will do that automatically
// App.Settings.Save();
// File.Copy(Path.Combine(App.BaseDirectory, "Settings.json"), Path.Combine(App.BaseDirectory, "Settings.json"));
Directories.Initialize(App.BaseDirectory);
}
CloseWindow();

View File

@ -26,7 +26,7 @@
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Automatically update Bloxstrap" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will check and automatically update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will automatically check and update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" />
@ -44,7 +44,7 @@
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Prompt on Roblox-forced channel change" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Confirm change if Roblox mandates when launching. Otherwise, it'll change automatically." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will ask you if you want to change the release channel to what Roblox mandates." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ChannelChangePromptingEnabled, Mode=TwoWay}" />