@@ -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
0 commit comments