Improve Roblox upgrade reliability

Addresses #3408
This commit is contained in:
pizzaboxer 2024-10-25 23:44:12 +01:00
parent c7ab37edf1
commit 6a93624040
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
8 changed files with 57 additions and 10 deletions

View File

@ -12,6 +12,8 @@
string Directory { get; } string Directory { get; }
string OldDirectory { get; }
string LockFilePath { get; } string LockFilePath { get; }
string ExecutablePath { get; } string ExecutablePath { get; }

View File

@ -18,6 +18,8 @@ namespace Bloxstrap.AppData
public override string Directory => Path.Combine(Paths.Roblox, "Player"); public override string Directory => Path.Combine(Paths.Roblox, "Player");
public string OldDirectory => Path.Combine(Paths.Roblox, "Player.old");
public AppState State => App.State.Prop.Player; public AppState State => App.State.Prop.Player;
public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>() public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()

View File

@ -12,6 +12,8 @@
public override string Directory => Path.Combine(Paths.Roblox, "Studio"); public override string Directory => Path.Combine(Paths.Roblox, "Studio");
public string OldDirectory => Path.Combine(Paths.Roblox, "Studio.old");
public AppState State => App.State.Prop.Studio; public AppState State => App.State.Prop.Studio;
public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>() public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()

View File

@ -452,8 +452,8 @@ namespace Bloxstrap
Process.Start(Paths.Process, args); Process.Start(Paths.Process, args);
} }
// average grace time between log being created and the window being shown // allow for window to show, since the log is created pretty far beforehand
Thread.Sleep(2000); Thread.Sleep(1000);
} }
public void Cancel() public void Cancel()
@ -631,19 +631,36 @@ namespace Bloxstrap
{ {
try try
{ {
// gross hack to see if roblox is still running // test to see if any files are in use
// i don't want to rely on mutexes because they can change, and will false flag for // if you have a better way to check for this, please let me know!
// running installations that are not by bloxstrap Directory.Move(AppData.Directory, AppData.OldDirectory);
File.Delete(AppData.ExecutablePath);
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine(LOG_IDENT, "Could not delete executable/folder, Roblox may still be running. Aborting update."); App.Logger.WriteLine(LOG_IDENT, "Could not clear old files, aborting update.");
App.Logger.WriteException(LOG_IDENT, ex); App.Logger.WriteException(LOG_IDENT, ex);
// 0x80070020 is the HRESULT that indicates that a process is still running
// (either RobloxPlayerBeta or RobloxCrashHandler), so we'll silently ignore it
if ((uint)ex.HResult != 0x80070020)
{
// ensure no files are marked as read-only for good measure
foreach (var file in Directory.GetFiles(AppData.Directory, "*", SearchOption.AllDirectories))
Filesystem.AssertReadOnly(file);
Frontend.ShowMessageBox(
Strings.Bootstrapper_FilesInUse,
_mustUpgrade ? MessageBoxImage.Error : MessageBoxImage.Warning
);
if (_mustUpgrade)
App.Terminate(ErrorCode.ERROR_CANCELLED);
}
return; return;
} }
Directory.Delete(AppData.Directory, true); Directory.Delete(AppData.OldDirectory, true);
} }
_isInstalling = true; _isInstalling = true;

View File

@ -115,7 +115,9 @@
{ {
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
WriteLine($"[{identifier}] {ex}"); string hresult = "0x" + ex.HResult.ToString("X8");
WriteLine($"[{identifier}] ({hresult}) {ex}");
Thread.CurrentThread.CurrentUICulture = Locale.CurrentCulture; Thread.CurrentThread.CurrentUICulture = Locale.CurrentCulture;
} }

View File

@ -168,6 +168,17 @@ namespace Bloxstrap.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Bloxstrap tried to upgrade Roblox but can&apos;t because Roblox&apos;s files are still in use.
///
///Please close any applications that may be using Roblox&apos;s files, and relaunch..
/// </summary>
public static string Bootstrapper_FilesInUse {
get {
return ResourceManager.GetString("Bootstrapper.FilesInUse", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to You must first install Bloxstrap before uninstalling.. /// Looks up a localized string similar to You must first install Bloxstrap before uninstalling..
/// </summary> /// </summary>

View File

@ -1241,4 +1241,10 @@ Would you like to enable test mode?</value>
<data name="Dialog.Exception.Version" xml:space="preserve"> <data name="Dialog.Exception.Version" xml:space="preserve">
<value>Version {0}</value> <value>Version {0}</value>
</data> </data>
<data name="Bootstrapper.FilesInUse" xml:space="preserve">
<value>Bloxstrap tried to upgrade Roblox but can't because Roblox's files are still in use.
Please close any applications that may be using Roblox's files, and relaunch.</value>
<comment>This is *not* for when Roblox is still running when trying to upgrade. This applies to files being open (i.e. image assets)</comment>
</data>
</root> </root>

View File

@ -157,6 +157,11 @@
{ {
clientVersion = await Http.GetJson<ClientVersion>("https://clientsettingscdn.roblox.com" + path); clientVersion = await Http.GetJson<ClientVersion>("https://clientsettingscdn.roblox.com" + path);
} }
catch (HttpRequestException)
{
// throw up the exception handler chain, as we shouldn't be the one handling it
throw;
}
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine(LOG_IDENT, "Failed to contact clientsettingscdn! Falling back to clientsettings..."); App.Logger.WriteLine(LOG_IDENT, "Failed to contact clientsettingscdn! Falling back to clientsettings...");