Skip to content

Commit 1166ef9

Browse files
committed
Improve install migrating
All Bloxstrap files are now copied instead of just the Bloxstrap executable
1 parent e075e9b commit 1166ef9

File tree

6 files changed

+103
-68
lines changed

6 files changed

+103
-68
lines changed

Bloxstrap/App.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public partial class App : Application
2727
public const string ProjectName = "Bloxstrap";
2828
public const string ProjectRepository = "pizzaboxer/bloxstrap";
2929

30+
// used only for communicating between app and menu - use Directories.Base for anything else
3031
public static string BaseDirectory = null!;
3132
public static bool ShouldSaveConfigs { get; set; } = false;
3233
public static bool IsSetupComplete { get; set; } = true;

Bloxstrap/Bootstrapper.cs

Lines changed: 89 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public partial class Bootstrapper
6767
private readonly CancellationTokenSource _cancelTokenSource = new();
6868

6969
private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid);
70+
private static string DesktopShortcutLocation => Path.Combine(Directories.Desktop, "Play Roblox.lnk");
7071

7172
private string? _launchCommandLine;
7273

@@ -114,6 +115,8 @@ public async Task Run()
114115

115116
await CheckLatestVersion();
116117

118+
CheckInstallMigration();
119+
117120
// if bloxstrap is installing for the first time but is running, prompt to close roblox
118121
// if roblox needs updating but is running, ignore update for now
119122
if (!Directory.Exists(_versionFolder) && CheckIfRunning(true) || App.State.Prop.VersionGuid != _versionGuid && !CheckIfRunning(false))
@@ -199,6 +202,69 @@ private async Task CheckLatestVersion()
199202
_versionPackageManifest = await PackageManifest.Get(_versionGuid);
200203
}
201204

205+
private void CheckInstallMigration()
206+
{
207+
// check if we've changed our install location since the last time we started
208+
// in which case, we'll have to copy over all our folders so we don't lose any mods and stuff
209+
210+
using RegistryKey? applicationKey = Registry.CurrentUser.OpenSubKey($@"Software\{App.ProjectName}", true);
211+
212+
string? oldInstallLocation = (string?)applicationKey?.GetValue("OldInstallLocation");
213+
214+
if (applicationKey is null || oldInstallLocation is null || oldInstallLocation == Directories.Base)
215+
return;
216+
217+
SetStatus("Migrating install location...");
218+
219+
if (Directory.Exists(oldInstallLocation))
220+
{
221+
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Moving all files in {oldInstallLocation} to {Directories.Base}...");
222+
223+
foreach (string oldFileLocation in Directory.GetFiles(oldInstallLocation, "*.*", SearchOption.AllDirectories))
224+
{
225+
string relativeFile = oldFileLocation.Substring(oldInstallLocation.Length + 1);
226+
string newFileLocation = Path.Combine(Directories.Base, relativeFile);
227+
string? newDirectory = Path.GetDirectoryName(newFileLocation);
228+
229+
try
230+
{
231+
if (!String.IsNullOrEmpty(newDirectory))
232+
Directory.CreateDirectory(newDirectory);
233+
234+
File.Move(oldFileLocation, newFileLocation, true);
235+
}
236+
catch (Exception ex)
237+
{
238+
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to move {oldFileLocation} to {newFileLocation}! {ex}");
239+
}
240+
}
241+
242+
try
243+
{
244+
Directory.Delete(oldInstallLocation, true);
245+
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Deleted old install location");
246+
}
247+
catch (Exception ex)
248+
{
249+
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to delete old install location! {ex}");
250+
}
251+
}
252+
253+
applicationKey.DeleteValue("OldInstallLocation");
254+
255+
// allow shortcuts to be re-registered
256+
if (Directory.Exists(Directories.StartMenu))
257+
Directory.Delete(Directories.StartMenu, true);
258+
259+
if (File.Exists(DesktopShortcutLocation))
260+
{
261+
File.Delete(DesktopShortcutLocation);
262+
App.Settings.Prop.CreateDesktopIcon = true;
263+
}
264+
265+
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Finished migrating install location!");
266+
}
267+
202268
private bool CheckIfRunning(bool shutdown)
203269
{
204270
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Checking if Roblox is running... (shutdown={shutdown})");
@@ -393,48 +459,32 @@ public void CancelInstall()
393459
#region App Install
394460
public static void Register()
395461
{
396-
RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}");
462+
using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
463+
{
464+
applicationKey.SetValue("InstallLocation", Directories.Base);
465+
}
397466

398-
// new install location selected, delete old one
399-
string? oldInstallLocation = (string?)applicationKey.GetValue("OldInstallLocation");
400-
if (!String.IsNullOrEmpty(oldInstallLocation) && oldInstallLocation != Directories.Base)
467+
// set uninstall key
468+
using (RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}"))
401469
{
402-
try
403-
{
404-
if (Directory.Exists(oldInstallLocation))
405-
Directory.Delete(oldInstallLocation, true);
406-
}
407-
catch (Exception)
408-
{
409-
// ignored
410-
}
470+
uninstallKey.SetValue("DisplayIcon", $"{Directories.Application},0");
471+
uninstallKey.SetValue("DisplayName", App.ProjectName);
472+
uninstallKey.SetValue("DisplayVersion", App.Version);
411473

412-
applicationKey.DeleteValue("OldInstallLocation");
413-
}
474+
if (uninstallKey.GetValue("InstallDate") is null)
475+
uninstallKey.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd"));
414476

415-
applicationKey.SetValue("InstallLocation", Directories.Base);
416-
applicationKey.Close();
477+
uninstallKey.SetValue("InstallLocation", Directories.Base);
478+
uninstallKey.SetValue("NoRepair", 1);
479+
uninstallKey.SetValue("Publisher", "pizzaboxer");
480+
uninstallKey.SetValue("ModifyPath", $"\"{Directories.Application}\" -menu");
481+
uninstallKey.SetValue("QuietUninstallString", $"\"{Directories.Application}\" -uninstall -quiet");
482+
uninstallKey.SetValue("UninstallString", $"\"{Directories.Application}\" -uninstall");
483+
uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}");
484+
uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest");
485+
}
417486

418-
// set uninstall key
419-
RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}");
420-
uninstallKey.SetValue("DisplayIcon", $"{Directories.Application},0");
421-
uninstallKey.SetValue("DisplayName", App.ProjectName);
422-
uninstallKey.SetValue("DisplayVersion", App.Version);
423-
424-
if (uninstallKey.GetValue("InstallDate") is null)
425-
uninstallKey.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd"));
426-
427-
uninstallKey.SetValue("InstallLocation", Directories.Base);
428-
uninstallKey.SetValue("NoRepair", 1);
429-
uninstallKey.SetValue("Publisher", "pizzaboxer");
430-
uninstallKey.SetValue("ModifyPath", $"\"{Directories.Application}\" -menu");
431-
uninstallKey.SetValue("QuietUninstallString", $"\"{Directories.Application}\" -uninstall -quiet");
432-
uninstallKey.SetValue("UninstallString", $"\"{Directories.Application}\" -uninstall");
433-
uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}");
434-
uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest");
435-
uninstallKey.Close();
436-
437-
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application version");
487+
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application");
438488
}
439489

440490
public static void CheckInstall()
@@ -485,10 +535,10 @@ public static void CheckInstall()
485535

486536
if (App.Settings.Prop.CreateDesktopIcon)
487537
{
488-
if (!File.Exists(Path.Combine(Directories.Desktop, "Play Roblox.lnk")))
538+
if (!File.Exists(DesktopShortcutLocation))
489539
{
490540
ShellLink.Shortcut.CreateShortcut(Directories.Application, "", Directories.Application, 0)
491-
.WriteToFile(Path.Combine(Directories.Desktop, "Play Roblox.lnk"));
541+
.WriteToFile(DesktopShortcutLocation);
492542
}
493543

494544
// one-time toggle, set it back to false

Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static void CheckIfRunning()
4141
if (process.MainModule?.FileName is null)
4242
continue;
4343

44-
if (!process.MainModule.FileName.Contains(App.BaseDirectory))
44+
if (!process.MainModule.FileName.Contains(Directories.Base))
4545
continue;
4646

4747
process.Kill();
@@ -56,7 +56,7 @@ public static void CheckIfRunning()
5656

5757
public static async Task CheckInstall()
5858
{
59-
string folderLocation = Path.Combine(App.BaseDirectory, "Integrations\\rbxfpsunlocker");
59+
string folderLocation = Path.Combine(Directories.Base, "Integrations\\rbxfpsunlocker");
6060
string fileLocation = Path.Combine(folderLocation, "rbxfpsunlocker.exe");
6161
string settingsLocation = Path.Combine(folderLocation, "settings");
6262

Bloxstrap/Helpers/JsonManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Bloxstrap.Helpers
1515
{
1616
public class JsonManager<T> where T : new()
1717
{
18-
public T Prop { get; set; } = new T();
18+
public T Prop { get; set; } = new();
1919
//public bool ShouldSave { get; set; } = true;
2020
public string FileLocation => Path.Combine(Directories.Base, $"{typeof(T).Name}.json");
2121
//public string? FileLocation { get; set; } = null;

Bloxstrap/ViewModels/MainWindowViewModel.cs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Windows;
44
using System.Windows.Input;
5+
using Bloxstrap.Helpers;
56
using Microsoft.Win32;
67
using CommunityToolkit.Mvvm.Input;
78
using Wpf.Ui.Controls.Interfaces;
@@ -39,19 +40,11 @@ private void ConfirmSettings()
3940
try
4041
{
4142
// check if we can write to the directory (a bit hacky but eh)
43+
string testFile = Path.Combine(App.BaseDirectory, $"{App.ProjectName}WriteTest.txt");
4244

43-
string testPath = App.BaseDirectory;
44-
string testFile = Path.Combine(testPath, $"{App.ProjectName}WriteTest.txt");
45-
bool testPathExists = Directory.Exists(testPath);
46-
47-
if (!testPathExists)
48-
Directory.CreateDirectory(testPath);
49-
45+
Directory.CreateDirectory(App.BaseDirectory);
5046
File.WriteAllText(testFile, "hi");
5147
File.Delete(testFile);
52-
53-
if (!testPathExists)
54-
Directory.Delete(testPath);
5548
}
5649
catch (UnauthorizedAccessException)
5750
{
@@ -71,22 +64,13 @@ private void ConfirmSettings()
7164

7265
if (App.BaseDirectory != _originalBaseDirectory)
7366
{
67+
App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}");
7468
App.ShowMessageBox($"{App.ProjectName} will install to the new location you've set the next time it runs.", MessageBoxImage.Information);
7569

76-
App.State.Prop.VersionGuid = "";
77-
78-
using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
79-
{
80-
registryKey.SetValue("InstallLocation", App.BaseDirectory);
81-
registryKey.SetValue("OldInstallLocation", _originalBaseDirectory);
82-
registryKey.Close();
83-
}
84-
85-
// preserve settings
86-
// we don't need to copy the bootstrapper over since the install process will do that automatically
87-
88-
// App.Settings.Save();
89-
// File.Copy(Path.Combine(App.BaseDirectory, "Settings.json"), Path.Combine(App.BaseDirectory, "Settings.json"));
70+
using RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}");
71+
registryKey.SetValue("InstallLocation", App.BaseDirectory);
72+
registryKey.SetValue("OldInstallLocation", _originalBaseDirectory);
73+
Directories.Initialize(App.BaseDirectory);
9074
}
9175

9276
CloseWindow();

Bloxstrap/Views/Pages/BehaviourPage.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<ui:CardControl.Header>
2727
<StackPanel>
2828
<TextBlock FontSize="14" Text="Automatically update Bloxstrap" />
29-
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will check and automatically update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
29+
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will automatically check and update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
3030
</StackPanel>
3131
</ui:CardControl.Header>
3232
<ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" />
@@ -44,7 +44,7 @@
4444
<ui:CardControl.Header>
4545
<StackPanel>
4646
<TextBlock FontSize="14" Text="Prompt on Roblox-forced channel change" />
47-
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Confirm change if Roblox mandates when launching. Otherwise, it'll change automatically." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
47+
<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}" />
4848
</StackPanel>
4949
</ui:CardControl.Header>
5050
<ui:ToggleSwitch IsChecked="{Binding ChannelChangePromptingEnabled, Mode=TwoWay}" />

0 commit comments

Comments
 (0)