diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index fb23a26..ee89778 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -193,27 +193,12 @@ namespace Bloxstrap await ApplyModifications(); } - // check if launch uri is set to our bootstrapper - // this doesn't go under register, so we check every launch - // just in case the stock bootstrapper changes it back + // check registry entries for every launch, just in case the stock bootstrapper changes it back if (IsStudioLaunch) - { -#if STUDIO_FEATURES - ProtocolHandler.Register("roblox-studio", "Roblox", Paths.Application); - ProtocolHandler.Register("roblox-studio-auth", "Roblox", Paths.Application); - - ProtocolHandler.RegisterRobloxPlace(Paths.Application); - ProtocolHandler.RegisterExtension(".rbxl"); - ProtocolHandler.RegisterExtension(".rbxlx"); -#endif - } + WindowsRegistry.RegisterStudio(); else - { - // TODO: there needs to be better helper functions for these - ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\""); - ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\""); - } + WindowsRegistry.RegisterPlayer(); await mutex.ReleaseAsync(); diff --git a/Bloxstrap/Installer.cs b/Bloxstrap/Installer.cs index e807455..c67672a 100644 --- a/Bloxstrap/Installer.cs +++ b/Bloxstrap/Installer.cs @@ -63,10 +63,7 @@ namespace Bloxstrap // only register player, for the scenario where the user installs bloxstrap, closes it, // and then launches from the website expecting it to work // studio can be implicitly registered when it's first launched manually - ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\""); - ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\""); - - // TODO: implicit installation needs to reregister studio + WindowsRegistry.RegisterPlayer(); if (CreateDesktopShortcuts) Shortcut.Create(Paths.Application, "", DesktopShortcut); @@ -79,6 +76,9 @@ namespace Bloxstrap App.State.Load(false); App.FastFlags.Load(false); + if (!String.IsNullOrEmpty(App.State.Prop.Studio.VersionGuid)) + WindowsRegistry.RegisterStudio(); + App.Logger.WriteLine(LOG_IDENT, "Installation finished"); } @@ -207,44 +207,38 @@ namespace Bloxstrap { playerStillInstalled = false; - ProtocolHandler.Unregister("roblox"); - ProtocolHandler.Unregister("roblox-player"); + WindowsRegistry.Unregister("roblox"); + WindowsRegistry.Unregister("roblox-player"); } else { - // revert launch uri handler to stock bootstrapper string playerPath = Path.Combine((string)playerFolder, "RobloxPlayerBeta.exe"); - ProtocolHandler.Register("roblox", "Roblox", playerPath); - ProtocolHandler.Register("roblox-player", "Roblox", playerPath); + WindowsRegistry.RegisterPlayer(playerPath, "%1"); } - using RegistryKey? studioBootstrapperKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\roblox-studio"); - if (studioBootstrapperKey is null) + using var studioKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\roblox-studio"); + var studioFolder = studioKey?.GetValue("InstallLocation"); + + if (studioKey is null || studioFolder is not string) { studioStillInstalled = false; -#if STUDIO_FEATURES - ProtocolHandler.Unregister("roblox-studio"); - ProtocolHandler.Unregister("roblox-studio-auth"); + WindowsRegistry.Unregister("roblox-studio"); + WindowsRegistry.Unregister("roblox-studio-auth"); - ProtocolHandler.Unregister("Roblox.Place"); - ProtocolHandler.Unregister(".rbxl"); - ProtocolHandler.Unregister(".rbxlx"); -#endif + WindowsRegistry.Unregister("Roblox.Place"); + WindowsRegistry.Unregister(".rbxl"); + WindowsRegistry.Unregister(".rbxlx"); } -#if STUDIO_FEATURES else { - string studioLocation = (string?)studioBootstrapperKey.GetValue("InstallLocation") + "RobloxStudioBeta.exe"; // points to studio exe instead of bootstrapper - ProtocolHandler.Register("roblox-studio", "Roblox", studioLocation); - ProtocolHandler.Register("roblox-studio-auth", "Roblox", studioLocation); + string studioPath = Path.Combine((string)studioFolder, "RobloxStudioBeta.exe"); + string studioLauncherPath = Path.Combine((string)studioFolder, "RobloxStudioLauncherBeta.exe"); - ProtocolHandler.RegisterRobloxPlace(studioLocation); + WindowsRegistry.RegisterStudioProtocol(studioPath, "%1"); + WindowsRegistry.RegisterStudioFileClass(studioPath, "-ide \"%1\""); } -#endif - - var cleanupSequence = new List { @@ -512,8 +506,7 @@ namespace Bloxstrap Registry.CurrentUser.DeleteSubKeyTree("Software\\Bloxstrap", false); - ProtocolHandler.Register("roblox", "Roblox", Paths.Application, "-player \"%1\""); - ProtocolHandler.Register("roblox-player", "Roblox", Paths.Application, "-player \"%1\""); + WindowsRegistry.RegisterPlayer(); string? oldV2Val = App.FastFlags.GetValue("FFlagDisableNewIGMinDUA"); diff --git a/Bloxstrap/ProtocolHandler.cs b/Bloxstrap/Utility/WindowsRegistry.cs similarity index 52% rename from Bloxstrap/ProtocolHandler.cs rename to Bloxstrap/Utility/WindowsRegistry.cs index ff57e2c..be2981c 100644 --- a/Bloxstrap/ProtocolHandler.cs +++ b/Bloxstrap/Utility/WindowsRegistry.cs @@ -1,18 +1,15 @@ -using System.Web; -using System.Windows; +using Microsoft.Win32; -using Microsoft.Win32; - -namespace Bloxstrap +namespace Bloxstrap.Utility { - static class ProtocolHandler + static class WindowsRegistry { private const string RobloxPlaceKey = "Roblox.Place"; - public static void Register(string key, string name, string handler, string handlerParam = "%1") + public static void RegisterProtocol(string key, string name, string handler, string handlerParam = "%1") { string handlerArgs = $"\"{handler}\" {handlerParam}"; - + using var uriKey = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{key}"); using var uriIconKey = uriKey.CreateSubKey("DefaultIcon"); using var uriCommandKey = uriKey.CreateSubKey(@"shell\open\command"); @@ -30,10 +27,56 @@ namespace Bloxstrap } } - public static void RegisterRobloxPlace(string handler) + /// + /// Registers Roblox Player protocols for Bloxstrap + /// + public static void RegisterPlayer() => RegisterPlayer(Paths.Application, "-player \"%1\""); + + public static void RegisterPlayer(string handler, string handlerParam) + { + RegisterProtocol("roblox", "Roblox", handler, handlerParam); + RegisterProtocol("roblox-player", "Roblox", handler, handlerParam); + } + + /// + /// Registers all Roblox Studio classes for Bloxstrap + /// + public static void RegisterStudio() + { + RegisterStudioProtocol(Paths.Application, "-studio \"%1\""); + RegisterStudioFileClass(Paths.Application, "-studio \"%1\""); + RegisterStudioFileTypes(); + } + + /// + /// Registers roblox-studio and roblox-studio-auth protocols + /// + /// + /// + public static void RegisterStudioProtocol(string handler, string handlerParam) + { + RegisterProtocol("roblox-studio", "Roblox", handler, handlerParam); + RegisterProtocol("roblox-studio-auth", "Roblox", handler, handlerParam); + } + + /// + /// Registers file associations for Roblox.Place class + /// + public static void RegisterStudioFileTypes() + { + RegisterStudioFileType(".rbxl"); + RegisterStudioFileType(".rbxlx"); + } + + /// + /// Registers Roblox.Place class + /// + /// + /// + public static void RegisterStudioFileClass(string handler, string handlerParam) { const string keyValue = "Roblox Place"; - string handlerArgs = $"\"{handler}\" -ide \"%1\""; + string handlerArgs = $"\"{handler}\" {handlerParam}"; string iconValue = $"{handler},0"; using RegistryKey uriKey = Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + RobloxPlaceKey); @@ -54,7 +97,7 @@ namespace Bloxstrap uriIconKey.SetValue("", iconValue); } - public static void RegisterExtension(string key) + public static void RegisterStudioFileType(string key) { using RegistryKey uriKey = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{key}"); uriKey.CreateSubKey(RobloxPlaceKey + @"\ShellNew");