Make install cancelling more reliable

This commit is contained in:
pizzaboxer 2023-02-11 21:31:19 +00:00
parent a0be3fa970
commit 0c4f7b4a27
4 changed files with 50 additions and 15 deletions

View File

@ -179,6 +179,7 @@ namespace Bloxstrap
{ {
dialog = Settings.Prop.BootstrapperStyle.GetNew(); dialog = Settings.Prop.BootstrapperStyle.GetNew();
bootstrapper.Dialog = dialog; bootstrapper.Dialog = dialog;
dialog.Bootstrapper = bootstrapper;
} }
Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t => Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t =>

View File

@ -64,6 +64,8 @@ namespace Bloxstrap
" <BaseUrl>http://www.roblox.com</BaseUrl>\n" + " <BaseUrl>http://www.roblox.com</BaseUrl>\n" +
"</Settings>\n"; "</Settings>\n";
private readonly CancellationTokenSource _cancelTokenSource = new();
private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid); private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid);
private string? _launchCommandLine; private string? _launchCommandLine;
@ -72,6 +74,7 @@ namespace Bloxstrap
private PackageManifest _versionPackageManifest = null!; private PackageManifest _versionPackageManifest = null!;
private string _versionFolder = null!; private string _versionFolder = null!;
private bool _isInstalling = false;
private double _progressIncrement; private double _progressIncrement;
private long _totalDownloadedBytes = 0; private long _totalDownloadedBytes = 0;
private int _packagesExtracted = 0; private int _packagesExtracted = 0;
@ -86,7 +89,7 @@ namespace Bloxstrap
_launchCommandLine = launchCommandLine; _launchCommandLine = launchCommandLine;
} }
public void SetStatus(string message) private void SetStatus(string message)
{ {
Debug.WriteLine($"[Bootstrapper] {message}"); Debug.WriteLine($"[Bootstrapper] {message}");
@ -296,24 +299,30 @@ namespace Bloxstrap
rbxFpsUnlocker.Kill(); rbxFpsUnlocker.Kill();
} }
public void CancelButtonClicked() public void CancelInstall()
{ {
if (Dialog is null || !Dialog.CancelEnabled) if (!_isInstalling)
{ {
App.Terminate(ERROR_INSTALL_USEREXIT); App.Terminate(ERROR_INSTALL_USEREXIT);
return; return;
} }
_cancelTokenSource.Cancel();
_cancelFired = true; _cancelFired = true;
try try
{ {
// clean up install
if (App.IsFirstRun) if (App.IsFirstRun)
Directory.Delete(Directories.Base, true); Directory.Delete(Directories.Base, true);
else if (Directory.Exists(_versionFolder)) else if (Directory.Exists(_versionFolder))
Directory.Delete(_versionFolder, true); Directory.Delete(_versionFolder, true);
} }
catch (Exception) { } catch (Exception e)
{
Debug.WriteLine("[Bootstrapper} Could not fully clean up installation!");
Debug.WriteLine(e);
}
App.Terminate(ERROR_INSTALL_USEREXIT); App.Terminate(ERROR_INSTALL_USEREXIT);
} }
@ -484,6 +493,8 @@ namespace Bloxstrap
private async Task InstallLatestVersion() private async Task InstallLatestVersion()
{ {
_isInstalling = true;
SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox..."); SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox...");
// check if we have at least 300 megabytes of free disk space // check if we have at least 300 megabytes of free disk space
@ -510,6 +521,9 @@ namespace Bloxstrap
foreach (Package package in _versionPackageManifest) foreach (Package package in _versionPackageManifest)
{ {
if (_cancelFired)
return;
// download all the packages synchronously // download all the packages synchronously
await DownloadPackage(package); await DownloadPackage(package);
@ -517,6 +531,9 @@ namespace Bloxstrap
ExtractPackage(package); ExtractPackage(package);
} }
if (_cancelFired)
return;
// allow progress bar to 100% before continuing (purely ux reasons lol) // allow progress bar to 100% before continuing (purely ux reasons lol)
await Task.Delay(1000); await Task.Delay(1000);
@ -535,6 +552,9 @@ namespace Bloxstrap
string appSettingsLocation = Path.Combine(_versionFolder, "AppSettings.xml"); string appSettingsLocation = Path.Combine(_versionFolder, "AppSettings.xml");
await File.WriteAllTextAsync(appSettingsLocation, AppSettings); await File.WriteAllTextAsync(appSettingsLocation, AppSettings);
if (_cancelFired)
return;
if (!FreshInstall) if (!FreshInstall)
{ {
ReShade.SynchronizeConfigFile(); ReShade.SynchronizeConfigFile();
@ -559,6 +579,8 @@ namespace Bloxstrap
Dialog.CancelEnabled = false; Dialog.CancelEnabled = false;
App.State.Prop.VersionGuid = _versionGuid; App.State.Prop.VersionGuid = _versionGuid;
_isInstalling = false;
} }
private async Task ApplyModifications() private async Task ApplyModifications()
@ -680,6 +702,9 @@ namespace Bloxstrap
private async Task DownloadPackage(Package package) private async Task DownloadPackage(Package package)
{ {
if (_cancelFired)
return;
string packageUrl = $"{DeployManager.BaseUrl}/{_versionGuid}-{package.Name}"; string packageUrl = $"{DeployManager.BaseUrl}/{_versionGuid}-{package.Name}";
string packageLocation = Path.Combine(Directories.Downloads, package.Signature); string packageLocation = Path.Combine(Directories.Downloads, package.Signature);
string robloxPackageLocation = Path.Combine(Directories.LocalAppData, "Roblox", "Downloads", package.Signature); string robloxPackageLocation = Path.Combine(Directories.LocalAppData, "Roblox", "Downloads", package.Signature);
@ -716,26 +741,30 @@ namespace Bloxstrap
if (!File.Exists(packageLocation)) if (!File.Exists(packageLocation))
{ {
Debug.WriteLine($"Downloading {package.Name}..."); Debug.WriteLine($"Downloading {package.Name} ({package.Signature})...");
if (_cancelFired)
return;
{ {
var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead); var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token);
var buffer = new byte[8192]; var buffer = new byte[4096];
await using var stream = await response.Content.ReadAsStreamAsync(); await using var stream = await response.Content.ReadAsStreamAsync(_cancelTokenSource.Token);
await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew); await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew, FileAccess.Write, FileShare.Delete);
while (true) while (true)
{ {
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); if (_cancelFired)
{
stream.Close();
fileStream.Close();
return;
}
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, _cancelTokenSource.Token);
if (bytesRead == 0) if (bytesRead == 0)
break; // we're done break; // we're done
await fileStream.WriteAsync(buffer, 0, bytesRead); await fileStream.WriteAsync(buffer, 0, bytesRead, _cancelTokenSource.Token);
_totalDownloadedBytes += bytesRead; _totalDownloadedBytes += bytesRead;
UpdateProgressbar(); UpdateProgressbar();

View File

@ -10,6 +10,8 @@ namespace Bloxstrap.Dialogs
{ {
public class BootstrapperDialogForm : Form, IBootstrapperDialog public class BootstrapperDialogForm : Form, IBootstrapperDialog
{ {
public Bootstrapper Bootstrapper { get; set; } = null!;
protected virtual string _message { get; set; } = "Please wait..."; protected virtual string _message { get; set; } = "Please wait...";
protected virtual ProgressBarStyle _progressStyle { get; set; } protected virtual ProgressBarStyle _progressStyle { get; set; }
protected virtual int _progressValue { get; set; } protected virtual int _progressValue { get; set; }
@ -117,6 +119,7 @@ namespace Bloxstrap.Dialogs
public void ButtonCancel_Click(object? sender, EventArgs e) public void ButtonCancel_Click(object? sender, EventArgs e)
{ {
Bootstrapper.CancelInstall();
this.Close(); this.Close();
} }
} }

View File

@ -4,6 +4,8 @@ namespace Bloxstrap.Dialogs
{ {
public interface IBootstrapperDialog public interface IBootstrapperDialog
{ {
public Bootstrapper Bootstrapper { get; set; }
string Message { get; set; } string Message { get; set; }
ProgressBarStyle ProgressStyle { get; set; } ProgressBarStyle ProgressStyle { get; set; }
int ProgressValue { get; set; } int ProgressValue { get; set; }