diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs
index 6f57fce..d938d46 100644
--- a/Bloxstrap/App.xaml.cs
+++ b/Bloxstrap/App.xaml.cs
@@ -5,12 +5,14 @@ using System.IO;
using System.Net.Http;
using System.Net;
using System.Reflection;
+using System.Threading.Tasks;
using System.Windows;
using Microsoft.Win32;
-using Bloxstrap.Models;
+using Bloxstrap.Dialogs;
using Bloxstrap.Enums;
using Bloxstrap.Helpers;
+using Bloxstrap.Models;
using Bloxstrap.Views;
namespace Bloxstrap
@@ -55,6 +57,7 @@ namespace Bloxstrap
{
Settings.Save();
State.Save();
+ Debug.WriteLine($"[App] Terminating with exit code {code}");
Environment.Exit(code);
}
@@ -167,7 +170,34 @@ namespace Bloxstrap
ShouldSaveConfigs = true;
DeployManager.Channel = Settings.Prop.Channel;
- Settings.Prop.BootstrapperStyle.Show(new Bootstrapper(commandLine));
+
+ // start bootstrapper and show the bootstrapper modal if we're not running silently
+ Bootstrapper bootstrapper = new Bootstrapper(commandLine);
+ IBootstrapperDialog? dialog = null;
+
+ if (!IsQuiet)
+ {
+ dialog = Settings.Prop.BootstrapperStyle.GetNew();
+ bootstrapper.Dialog = dialog;
+ dialog.Bootstrapper = bootstrapper;
+ }
+
+ Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t =>
+ {
+ // TODO: add error logging
+
+ if (t.Exception is null)
+ return;
+
+#if DEBUG
+ throw t.Exception;
+#else
+ dialog?.ShowError(t.Exception.ToString());
+#endif
+ });
+
+ dialog?.ShowBootstrapper();
+ bootstrapperTask.Wait();
}
Terminate();
diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs
index 31fc182..93aecc9 100644
--- a/Bloxstrap/Bootstrapper.cs
+++ b/Bloxstrap/Bootstrapper.cs
@@ -28,7 +28,6 @@ namespace Bloxstrap
public const int ERROR_SUCCESS = 0;
public const int ERROR_INSTALL_USEREXIT = 1602;
public const int ERROR_INSTALL_FAILURE = 1603;
- public const int ERROR_PRODUCT_UNINSTALLED = 1614;
// in case a new package is added, you can find the corresponding directory
// by opening the stock bootstrapper in a hex editor
@@ -58,38 +57,46 @@ namespace Bloxstrap
{ "extracontent-places.zip", @"ExtraContent\places\" },
};
- private static readonly string AppSettings =
+ private const string AppSettings =
"\n" +
"\n" +
" content\n" +
" http://www.roblox.com\n" +
"\n";
- private string? LaunchCommandLine;
+ private readonly CancellationTokenSource _cancelTokenSource = new();
- private string VersionGuid = null!;
- private PackageManifest VersionPackageManifest = null!;
- private string VersionFolder = null!;
+ private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid);
- private readonly bool FreshInstall;
+ private string? _launchCommandLine;
- private double ProgressIncrement;
- private long TotalBytes = 0;
- private long TotalDownloadedBytes = 0;
- private int PackagesExtracted = 0;
- private bool CancelFired = false;
+ private string _versionGuid = null!;
+ private PackageManifest _versionPackageManifest = null!;
+ private string _versionFolder = null!;
- public IBootstrapperDialog Dialog = null!;
+ private bool _isInstalling = false;
+ private double _progressIncrement;
+ private long _totalDownloadedBytes = 0;
+ private int _packagesExtracted = 0;
+ private bool _cancelFired = false;
+
+ public IBootstrapperDialog? Dialog = null;
#endregion
#region Core
public Bootstrapper(string? launchCommandLine = null)
{
- LaunchCommandLine = launchCommandLine;
- FreshInstall = String.IsNullOrEmpty(App.State.Prop.VersionGuid);
+ _launchCommandLine = launchCommandLine;
+ }
+
+ private void SetStatus(string message)
+ {
+ Debug.WriteLine($"[Bootstrapper] {message}");
+
+ if (Dialog is not null)
+ Dialog.Message = message;
}
- // this is called from BootstrapperStyleForm.SetupDialog()
public async Task Run()
{
if (App.IsUninstall)
@@ -107,14 +114,11 @@ namespace Bloxstrap
// if bloxstrap is installing for the first time but is running, prompt to close roblox
// if roblox needs updating but is running, ignore update for now
- if (!Directory.Exists(VersionFolder) && CheckIfRunning(true) || App.State.Prop.VersionGuid != VersionGuid && !CheckIfRunning(false))
+ if (!Directory.Exists(_versionFolder) && CheckIfRunning(true) || App.State.Prop.VersionGuid != _versionGuid && !CheckIfRunning(false))
await InstallLatestVersion();
if (App.IsFirstRun)
- {
- //App.Settings.ShouldSave = App.State.ShouldSave = true;
App.ShouldSaveConfigs = true;
- }
await ApplyModifications();
@@ -129,7 +133,7 @@ namespace Bloxstrap
App.State.Save();
if (App.IsFirstRun && App.IsNoLaunch)
- Dialog.ShowSuccess($"{App.ProjectName} has successfully installed");
+ Dialog?.ShowSuccess($"{App.ProjectName} has successfully installed");
else if (!App.IsNoLaunch)
await StartRoblox();
}
@@ -140,10 +144,10 @@ namespace Bloxstrap
var releaseInfo = await Utilities.GetJson($"https://api.github.com/repos/{App.ProjectRepository}/releases/latest");
- if (releaseInfo is null || releaseInfo.Name is null || releaseInfo.Assets is null || currentVersion == releaseInfo.Name)
+ if (releaseInfo?.Assets is null || currentVersion == releaseInfo.Name)
return;
- Dialog.Message = $"Getting the latest {App.ProjectName}...";
+ SetStatus($"Getting the latest {App.ProjectName}...");
// 64-bit is always the first option
GithubReleaseAsset asset = releaseInfo.Assets[Environment.Is64BitOperatingSystem ? 0 : 1];
@@ -180,12 +184,12 @@ namespace Bloxstrap
private async Task CheckLatestVersion()
{
- Dialog.Message = "Connecting to Roblox...";
+ SetStatus("Connecting to Roblox...");
ClientVersion clientVersion = await DeployManager.GetLastDeploy(App.Settings.Prop.Channel);
- VersionGuid = clientVersion.VersionGuid;
- VersionFolder = Path.Combine(Directories.Versions, VersionGuid);
- VersionPackageManifest = await PackageManifest.Get(VersionGuid);
+ _versionGuid = clientVersion.VersionGuid;
+ _versionFolder = Path.Combine(Directories.Versions, _versionGuid);
+ _versionPackageManifest = await PackageManifest.Get(_versionGuid);
}
private bool CheckIfRunning(bool shutdown)
@@ -197,7 +201,7 @@ namespace Bloxstrap
if (shutdown)
{
- Dialog.PromptShutdown();
+ Dialog?.PromptShutdown();
try
{
@@ -219,24 +223,24 @@ namespace Bloxstrap
{
string startEventName = App.ProjectName.Replace(" ", "") + "StartEvent";
- Dialog.Message = "Starting Roblox...";
+ SetStatus("Starting Roblox...");
- if (LaunchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
+ if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
{
Utilities.OpenWebsite("https://www.roblox.com/games");
return;
}
// launch time isn't really required for all launches, but it's usually just safest to do this
- LaunchCommandLine += " --launchtime=" + DateTimeOffset.Now.ToUnixTimeMilliseconds();
+ _launchCommandLine += " --launchtime=" + DateTimeOffset.Now.ToUnixTimeMilliseconds();
if (App.Settings.Prop.Channel.ToLower() != DeployManager.DefaultChannel.ToLower())
- LaunchCommandLine += " -channel " + App.Settings.Prop.Channel.ToLower();
+ _launchCommandLine += " -channel " + App.Settings.Prop.Channel.ToLower();
- LaunchCommandLine += " -startEvent " + startEventName;
+ _launchCommandLine += " -startEvent " + startEventName;
bool shouldWait = false;
- Process gameClient = Process.Start(Path.Combine(VersionFolder, "RobloxPlayerBeta.exe"), LaunchCommandLine);
+ Process gameClient = Process.Start(Path.Combine(_versionFolder, "RobloxPlayerBeta.exe"), _launchCommandLine);
Process? rbxFpsUnlocker = null;
DiscordRichPresence? richPresence = null;
Mutex? singletonMutex = null;
@@ -286,7 +290,7 @@ namespace Bloxstrap
return;
// keep bloxstrap open in the background
- Dialog.HideBootstrapper();
+ Dialog?.CloseBootstrapper();
await gameClient.WaitForExitAsync();
richPresence?.Dispose();
@@ -295,25 +299,31 @@ namespace Bloxstrap
rbxFpsUnlocker.Kill();
}
- public void CancelButtonClicked()
+ public void CancelInstall()
{
- if (!Dialog.CancelEnabled)
+ if (!_isInstalling)
{
App.Terminate(ERROR_INSTALL_USEREXIT);
return;
}
- CancelFired = true;
+ _cancelTokenSource.Cancel();
+ _cancelFired = true;
try
{
+ // clean up install
if (App.IsFirstRun)
Directory.Delete(Directories.Base, true);
- else if (Directory.Exists(VersionFolder))
- Directory.Delete(VersionFolder, true);
+ else if (Directory.Exists(_versionFolder))
+ 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);
}
#endregion
@@ -332,7 +342,10 @@ namespace Bloxstrap
if (Directory.Exists(oldInstallLocation))
Directory.Delete(oldInstallLocation, true);
}
- catch (Exception) { }
+ catch (Exception)
+ {
+ // ignored
+ }
applicationKey.DeleteValue("OldInstallLocation");
}
@@ -415,7 +428,7 @@ namespace Bloxstrap
{
CheckIfRunning(true);
- Dialog.Message = $"Uninstalling {App.ProjectName}...";
+ SetStatus($"Uninstalling {App.ProjectName}...");
//App.Settings.ShouldSave = false;
App.ShouldSaveConfigs = false;
@@ -460,31 +473,29 @@ namespace Bloxstrap
Debug.WriteLine($"Could not fully uninstall! ({e})");
}
- Dialog.ShowSuccess($"{App.ProjectName} has succesfully uninstalled");
-
- App.Terminate();
+ Dialog?.ShowSuccess($"{App.ProjectName} has succesfully uninstalled");
}
#endregion
#region Roblox Install
private void UpdateProgressbar()
{
- int newProgress = (int)Math.Floor(ProgressIncrement * TotalDownloadedBytes);
+ int newProgress = (int)Math.Floor(_progressIncrement * _totalDownloadedBytes);
// bugcheck: if we're restoring a file from a package, it'll incorrectly increment the progress beyond 100
// too lazy to fix properly so lol
if (newProgress > 100)
return;
- Dialog.ProgressValue = newProgress;
+ if (Dialog is not null)
+ Dialog.ProgressValue = newProgress;
}
private async Task InstallLatestVersion()
{
- if (FreshInstall)
- Dialog.Message = "Installing Roblox...";
- else
- Dialog.Message = "Upgrading Roblox...";
+ _isInstalling = true;
+
+ SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox...");
// check if we have at least 300 megabytes of free disk space
if (Utilities.GetFreeDiskSpace(Directories.Base) < 1024*1024*300)
@@ -496,44 +507,54 @@ namespace Bloxstrap
Directory.CreateDirectory(Directories.Base);
- Dialog.CancelEnabled = true;
- Dialog.ProgressStyle = ProgressBarStyle.Continuous;
+ if (Dialog is not null)
+ {
+ Dialog.CancelEnabled = true;
+ Dialog.ProgressStyle = ProgressBarStyle.Continuous;
+ }
// compute total bytes to download
-
- foreach (Package package in VersionPackageManifest)
- TotalBytes += package.PackedSize;
-
- ProgressIncrement = (double)1 / TotalBytes * 100;
+ _progressIncrement = (double)100 / _versionPackageManifest.Sum(package => package.PackedSize);
Directory.CreateDirectory(Directories.Downloads);
Directory.CreateDirectory(Directories.Versions);
- foreach (Package package in VersionPackageManifest)
+ foreach (Package package in _versionPackageManifest)
{
+ if (_cancelFired)
+ return;
+
// download all the packages synchronously
await DownloadPackage(package);
- // extract the package immediately after download
+ // extract the package immediately after download asynchronously
ExtractPackage(package);
}
+ if (_cancelFired)
+ return;
+
// allow progress bar to 100% before continuing (purely ux reasons lol)
await Task.Delay(1000);
- Dialog.ProgressStyle = ProgressBarStyle.Marquee;
-
- Dialog.Message = "Configuring Roblox...";
+ if (Dialog is not null)
+ {
+ Dialog.ProgressStyle = ProgressBarStyle.Marquee;
+ SetStatus("Configuring Roblox...");
+ }
// wait for all packages to finish extracting
- while (PackagesExtracted < VersionPackageManifest.Count)
+ while (_packagesExtracted < _versionPackageManifest.Count)
{
await Task.Delay(100);
}
- string appSettingsLocation = Path.Combine(VersionFolder, "AppSettings.xml");
+ string appSettingsLocation = Path.Combine(_versionFolder, "AppSettings.xml");
await File.WriteAllTextAsync(appSettingsLocation, AppSettings);
+ if (_cancelFired)
+ return;
+
if (!FreshInstall)
{
ReShade.SynchronizeConfigFile();
@@ -541,27 +562,30 @@ namespace Bloxstrap
// let's take this opportunity to delete any packages we don't need anymore
foreach (string filename in Directory.GetFiles(Directories.Downloads))
{
- if (!VersionPackageManifest.Exists(package => filename.Contains(package.Signature)))
+ if (!_versionPackageManifest.Exists(package => filename.Contains(package.Signature)))
File.Delete(filename);
}
string oldVersionFolder = Path.Combine(Directories.Versions, App.State.Prop.VersionGuid);
- if (VersionGuid != App.State.Prop.VersionGuid && Directory.Exists(oldVersionFolder))
+ if (_versionGuid != App.State.Prop.VersionGuid && Directory.Exists(oldVersionFolder))
{
// and also to delete our old version folder
Directory.Delete(oldVersionFolder, true);
}
}
- Dialog.CancelEnabled = false;
+ if (Dialog is not null)
+ Dialog.CancelEnabled = false;
- App.State.Prop.VersionGuid = VersionGuid;
+ App.State.Prop.VersionGuid = _versionGuid;
+
+ _isInstalling = false;
}
private async Task ApplyModifications()
{
- Dialog.Message = "Applying Roblox modifications...";
+ SetStatus("Applying Roblox modifications...");
string modFolder = Path.Combine(Directories.Modifications);
@@ -599,7 +623,7 @@ namespace Bloxstrap
foreach (string file in modFolderFiles)
{
string fileModFolder = Path.Combine(modFolder, file);
- string fileVersionFolder = Path.Combine(VersionFolder, file);
+ string fileVersionFolder = Path.Combine(_versionFolder, file);
if (File.Exists(fileVersionFolder))
{
@@ -635,7 +659,7 @@ namespace Bloxstrap
catch (InvalidOperationException)
{
// package doesn't exist, likely mistakenly placed file
- string versionFileLocation = Path.Combine(VersionFolder, fileLocation);
+ string versionFileLocation = Path.Combine(_versionFolder, fileLocation);
File.Delete(versionFileLocation);
@@ -678,7 +702,10 @@ namespace Bloxstrap
private async Task DownloadPackage(Package package)
{
- string packageUrl = $"{DeployManager.BaseUrl}/{VersionGuid}-{package.Name}";
+ if (_cancelFired)
+ return;
+
+ string packageUrl = $"{DeployManager.BaseUrl}/{_versionGuid}-{package.Name}";
string packageLocation = Path.Combine(Directories.Downloads, package.Signature);
string robloxPackageLocation = Path.Combine(Directories.LocalAppData, "Roblox", "Downloads", package.Signature);
@@ -695,7 +722,7 @@ namespace Bloxstrap
else
{
Debug.WriteLine($"{package.Name} is already downloaded, skipping...");
- TotalDownloadedBytes += package.PackedSize;
+ _totalDownloadedBytes += package.PackedSize;
UpdateProgressbar();
return;
}
@@ -707,35 +734,39 @@ namespace Bloxstrap
Debug.WriteLine($"Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder...");
File.Copy(robloxPackageLocation, packageLocation);
- TotalDownloadedBytes += package.PackedSize;
+ _totalDownloadedBytes += package.PackedSize;
UpdateProgressbar();
return;
}
if (!File.Exists(packageLocation))
{
- Debug.WriteLine($"Downloading {package.Name}...");
-
- if (CancelFired)
- return;
+ Debug.WriteLine($"Downloading {package.Name} ({package.Signature})...");
{
- var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead);
- var buffer = new byte[8192];
+ var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token);
+ var buffer = new byte[4096];
- await using var stream = await response.Content.ReadAsStreamAsync();
- await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew);
+ await using var stream = await response.Content.ReadAsStreamAsync(_cancelTokenSource.Token);
+ await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew, FileAccess.Write, FileShare.Delete);
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)
break; // we're done
- await fileStream.WriteAsync(buffer, 0, bytesRead);
+ await fileStream.WriteAsync(buffer, 0, bytesRead, _cancelTokenSource.Token);
- TotalDownloadedBytes += bytesRead;
+ _totalDownloadedBytes += bytesRead;
UpdateProgressbar();
}
}
@@ -746,13 +777,12 @@ namespace Bloxstrap
private async void ExtractPackage(Package package)
{
- if (CancelFired)
+ if (_cancelFired)
return;
string packageLocation = Path.Combine(Directories.Downloads, package.Signature);
- string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]);
+ string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]);
string extractPath;
- string? directory;
Debug.WriteLine($"Extracting {package.Name} to {packageFolder}...");
@@ -760,7 +790,7 @@ namespace Bloxstrap
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
- if (CancelFired)
+ if (_cancelFired)
return;
if (entry.FullName.EndsWith('\\'))
@@ -770,7 +800,7 @@ namespace Bloxstrap
//Debug.WriteLine($"[{package.Name}] Writing {extractPath}...");
- directory = Path.GetDirectoryName(extractPath);
+ string? directory = Path.GetDirectoryName(extractPath);
if (directory is null)
continue;
@@ -783,12 +813,12 @@ namespace Bloxstrap
Debug.WriteLine($"Finished extracting {package.Name}");
- PackagesExtracted += 1;
+ _packagesExtracted += 1;
}
private void ExtractFileFromPackage(string packageName, string fileName)
{
- Package? package = VersionPackageManifest.Find(x => x.Name == packageName);
+ Package? package = _versionPackageManifest.Find(x => x.Name == packageName);
if (package is null)
return;
@@ -796,7 +826,7 @@ namespace Bloxstrap
DownloadPackage(package).GetAwaiter().GetResult();
string packageLocation = Path.Combine(Directories.Downloads, package.Signature);
- string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]);
+ string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]);
using ZipArchive archive = ZipFile.OpenRead(packageLocation);
diff --git a/Bloxstrap/Dialogs/BootstrapperDialogForm.cs b/Bloxstrap/Dialogs/BootstrapperDialogForm.cs
index 6ec3ee1..62e2a50 100644
--- a/Bloxstrap/Dialogs/BootstrapperDialogForm.cs
+++ b/Bloxstrap/Dialogs/BootstrapperDialogForm.cs
@@ -10,9 +10,7 @@ namespace Bloxstrap.Dialogs
{
public class BootstrapperDialogForm : Form, IBootstrapperDialog
{
- public Bootstrapper? Bootstrapper { get; set; }
-
- protected override bool ShowWithoutActivation => App.IsQuiet;
+ public Bootstrapper Bootstrapper { get; set; } = null!;
protected virtual string _message { get; set; } = "Please wait...";
protected virtual ProgressBarStyle _progressStyle { get; set; }
@@ -67,11 +65,6 @@ namespace Bloxstrap.Dialogs
}
}
- public BootstrapperDialogForm(Bootstrapper? bootstrapper = null)
- {
- Bootstrapper = bootstrapper;
- }
-
public void ScaleWindow()
{
this.Size = this.MinimumSize = this.MaximumSize = WindowScaling.GetScaledSize(this.Size);
@@ -88,64 +81,16 @@ namespace Bloxstrap.Dialogs
{
this.Text = App.ProjectName;
this.Icon = App.Settings.Prop.BootstrapperIcon.GetIcon();
-
- if (Bootstrapper is null)
- {
- Message = "Style preview - Click Cancel to close";
- CancelEnabled = true;
- }
- else
- {
- Bootstrapper.Dialog = this;
- Task.Run(RunBootstrapper);
- }
}
+ public void ShowBootstrapper() => this.ShowDialog();
- public async void RunBootstrapper()
- {
- if (Bootstrapper is null)
- return;
-
-#if DEBUG
- await Bootstrapper.Run();
-#else
- try
- {
- await Bootstrapper.Run();
- }
- catch (Exception ex)
- {
- // string message = String.Format("{0}: {1}", ex.GetType(), ex.Message);
- string message = ex.ToString();
- ShowError(message);
- }
-#endif
-
- App.Terminate();
- }
-
- public void ShowAsPreview()
- {
- this.ShowDialog();
- }
-
- public void ShowAsBootstrapper()
- {
- System.Windows.Forms.Application.Run(this);
- }
-
- public virtual void HideBootstrapper()
+ public virtual void CloseBootstrapper()
{
if (this.InvokeRequired)
- {
- this.Invoke(HideBootstrapper);
- }
+ this.Invoke(CloseBootstrapper);
else
- {
- this.Opacity = 0;
- this.ShowInTaskbar = false;
- }
+ this.Close();
}
public virtual void ShowSuccess(string message)
@@ -174,10 +119,8 @@ namespace Bloxstrap.Dialogs
public void ButtonCancel_Click(object? sender, EventArgs e)
{
- if (Bootstrapper is null)
- this.Close();
- else
- Task.Run(() => Bootstrapper.CancelButtonClicked());
+ Bootstrapper.CancelInstall();
+ this.Close();
}
}
}
diff --git a/Bloxstrap/Dialogs/IBootstrapperDialog.cs b/Bloxstrap/Dialogs/IBootstrapperDialog.cs
index 0887dff..3cbe197 100644
--- a/Bloxstrap/Dialogs/IBootstrapperDialog.cs
+++ b/Bloxstrap/Dialogs/IBootstrapperDialog.cs
@@ -4,17 +4,15 @@ namespace Bloxstrap.Dialogs
{
public interface IBootstrapperDialog
{
- Bootstrapper? Bootstrapper { get; set; }
+ public Bootstrapper Bootstrapper { get; set; }
string Message { get; set; }
ProgressBarStyle ProgressStyle { get; set; }
int ProgressValue { get; set; }
bool CancelEnabled { get; set; }
- void RunBootstrapper();
- void ShowAsPreview();
- void ShowAsBootstrapper();
- void HideBootstrapper();
+ void ShowBootstrapper();
+ void CloseBootstrapper();
void ShowSuccess(string message);
void ShowError(string message);
void PromptShutdown();
diff --git a/Bloxstrap/Dialogs/LegacyDialog2009.cs b/Bloxstrap/Dialogs/LegacyDialog2009.cs
index 705380e..684870b 100644
--- a/Bloxstrap/Dialogs/LegacyDialog2009.cs
+++ b/Bloxstrap/Dialogs/LegacyDialog2009.cs
@@ -32,7 +32,7 @@ namespace Bloxstrap.Dialogs
set => this.buttonCancel.Enabled = value;
}
- public LegacyDialog2009(Bootstrapper? bootstrapper = null) : base(bootstrapper)
+ public LegacyDialog2009()
{
InitializeComponent();
diff --git a/Bloxstrap/Dialogs/LegacyDialog2011.cs b/Bloxstrap/Dialogs/LegacyDialog2011.cs
index ca27498..1c21c5b 100644
--- a/Bloxstrap/Dialogs/LegacyDialog2011.cs
+++ b/Bloxstrap/Dialogs/LegacyDialog2011.cs
@@ -33,7 +33,7 @@ namespace Bloxstrap.Dialogs
set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value;
}
- public LegacyDialog2011(Bootstrapper? bootstrapper = null) : base(bootstrapper)
+ public LegacyDialog2011()
{
InitializeComponent();
diff --git a/Bloxstrap/Dialogs/ProgressDialog.cs b/Bloxstrap/Dialogs/ProgressDialog.cs
index a7316ca..a1ec9ec 100644
--- a/Bloxstrap/Dialogs/ProgressDialog.cs
+++ b/Bloxstrap/Dialogs/ProgressDialog.cs
@@ -34,7 +34,7 @@ namespace Bloxstrap.Dialogs
set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value;
}
- public ProgressDialog(Bootstrapper? bootstrapper = null) : base(bootstrapper)
+ public ProgressDialog()
{
InitializeComponent();
diff --git a/Bloxstrap/Dialogs/VistaDialog.cs b/Bloxstrap/Dialogs/VistaDialog.cs
index fdde6d7..589ad79 100644
--- a/Bloxstrap/Dialogs/VistaDialog.cs
+++ b/Bloxstrap/Dialogs/VistaDialog.cs
@@ -13,58 +13,54 @@ namespace Bloxstrap.Dialogs
public partial class VistaDialog : BootstrapperDialogForm
{
- private TaskDialogPage Dialog;
+ private TaskDialogPage _dialogPage;
- protected override string _message
+ protected sealed override string _message
{
- get => Dialog.Heading ?? "";
- set => Dialog.Heading = value;
+ get => _dialogPage.Heading ?? "";
+ set => _dialogPage.Heading = value;
}
- protected override ProgressBarStyle _progressStyle
+ protected sealed override ProgressBarStyle _progressStyle
{
set
{
- if (Dialog.ProgressBar is null)
+ if (_dialogPage.ProgressBar is null)
return;
- switch (value)
+ _dialogPage.ProgressBar.State = value switch
{
- case ProgressBarStyle.Continuous:
- case ProgressBarStyle.Blocks:
- Dialog.ProgressBar.State = TaskDialogProgressBarState.Normal;
- break;
-
- case ProgressBarStyle.Marquee:
- Dialog.ProgressBar.State = TaskDialogProgressBarState.Marquee;
- break;
- }
+ ProgressBarStyle.Continuous => TaskDialogProgressBarState.Normal,
+ ProgressBarStyle.Blocks => TaskDialogProgressBarState.Normal,
+ ProgressBarStyle.Marquee => TaskDialogProgressBarState.Marquee,
+ _ => _dialogPage.ProgressBar.State
+ };
}
}
- protected override int _progressValue
+ protected sealed override int _progressValue
{
- get => Dialog.ProgressBar is null ? 0 : Dialog.ProgressBar.Value;
+ get => _dialogPage.ProgressBar?.Value ?? 0;
set
{
- if (Dialog.ProgressBar is null)
+ if (_dialogPage.ProgressBar is null)
return;
- Dialog.ProgressBar.Value = value;
+ _dialogPage.ProgressBar.Value = value;
}
}
- protected override bool _cancelEnabled
+ protected sealed override bool _cancelEnabled
{
- get => Dialog.Buttons[0].Enabled;
- set => Dialog.Buttons[0].Enabled = value;
+ get => _dialogPage.Buttons[0].Enabled;
+ set => _dialogPage.Buttons[0].Enabled = value;
}
- public VistaDialog(Bootstrapper? bootstrapper = null) : base(bootstrapper)
+ public VistaDialog()
{
InitializeComponent();
- Dialog = new TaskDialogPage()
+ _dialogPage = new TaskDialogPage()
{
Icon = new TaskDialogIcon(App.Settings.Prop.BootstrapperIcon.GetIcon()),
Caption = App.ProjectName,
@@ -79,7 +75,7 @@ namespace Bloxstrap.Dialogs
_message = "Please wait...";
_cancelEnabled = false;
- Dialog.Buttons[0].Click += (sender, e) => ButtonCancel_Click(sender, e);
+ _dialogPage.Buttons[0].Click += ButtonCancel_Click;
SetupDialog();
}
@@ -100,12 +96,10 @@ namespace Bloxstrap.Dialogs
Buttons = { TaskDialogButton.OK }
};
- successDialog.Buttons[0].Click += (sender, e) => App.Terminate();
+ successDialog.Buttons[0].Click += (_, _) => App.Terminate();
- if (!App.IsQuiet)
- Dialog.Navigate(successDialog);
-
- Dialog = successDialog;
+ _dialogPage.Navigate(successDialog);
+ _dialogPage = successDialog;
}
}
@@ -134,33 +128,25 @@ namespace Bloxstrap.Dialogs
errorDialog.Buttons[0].Click += (sender, e) => App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE);
- if (!App.IsQuiet)
- Dialog.Navigate(errorDialog);
-
- Dialog = errorDialog;
+ _dialogPage.Navigate(errorDialog);
+ _dialogPage = errorDialog;
}
}
- public override void HideBootstrapper()
+ public override void CloseBootstrapper()
{
if (this.InvokeRequired)
{
- this.Invoke(HideBootstrapper);
+ this.Invoke(CloseBootstrapper);
}
else
{
- if (Dialog.BoundDialog is null)
- return;
-
- Dialog.BoundDialog.Close();
+ _dialogPage.BoundDialog?.Close();
+ base.CloseBootstrapper();
}
}
- private void VistaDialog_Load(object sender, EventArgs e)
- {
- if (!App.IsQuiet)
- TaskDialog.ShowDialog(Dialog);
- }
+ private void VistaDialog_Load(object sender, EventArgs e) => TaskDialog.ShowDialog(_dialogPage);
}
}
diff --git a/Bloxstrap/Enums/BootstrapperStyle.cs b/Bloxstrap/Enums/BootstrapperStyle.cs
index fc9f7ba..9fadd0f 100644
--- a/Bloxstrap/Enums/BootstrapperStyle.cs
+++ b/Bloxstrap/Enums/BootstrapperStyle.cs
@@ -14,28 +14,16 @@ namespace Bloxstrap.Enums
public static class BootstrapperStyleEx
{
- public static void Show(this BootstrapperStyle bootstrapperStyle, Bootstrapper? bootstrapper = null)
+ public static IBootstrapperDialog GetNew(this BootstrapperStyle bootstrapperStyle)
{
- IBootstrapperDialog dialog = bootstrapperStyle switch
+ return bootstrapperStyle switch
{
- BootstrapperStyle.VistaDialog => new VistaDialog(bootstrapper),
- BootstrapperStyle.LegacyDialog2009 => new LegacyDialog2009(bootstrapper),
- BootstrapperStyle.LegacyDialog2011 => new LegacyDialog2011(bootstrapper),
- BootstrapperStyle.ProgressDialog => new ProgressDialog(bootstrapper),
- _ => new ProgressDialog(bootstrapper)
+ BootstrapperStyle.VistaDialog => new VistaDialog(),
+ BootstrapperStyle.LegacyDialog2009 => new LegacyDialog2009(),
+ BootstrapperStyle.LegacyDialog2011 => new LegacyDialog2011(),
+ BootstrapperStyle.ProgressDialog => new ProgressDialog(),
+ _ => new ProgressDialog()
};
-
- if (bootstrapper is null)
- {
- dialog.ShowAsPreview();
- }
- else
- {
- if (App.IsQuiet)
- dialog.HideBootstrapper();
-
- dialog.ShowAsBootstrapper();
- }
}
}
}
diff --git a/Bloxstrap/ViewModels/BootstrapperViewModel.cs b/Bloxstrap/ViewModels/BootstrapperViewModel.cs
index 1420644..da73f0f 100644
--- a/Bloxstrap/ViewModels/BootstrapperViewModel.cs
+++ b/Bloxstrap/ViewModels/BootstrapperViewModel.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using Bloxstrap.Dialogs;
using Bloxstrap.Enums;
using Bloxstrap.Views;
using CommunityToolkit.Mvvm.Input;
@@ -20,7 +21,14 @@ namespace Bloxstrap.ViewModels
public ICommand PreviewBootstrapperCommand => new RelayCommand(PreviewBootstrapper);
- private void PreviewBootstrapper() => App.Settings.Prop.BootstrapperStyle.Show();
+ private void PreviewBootstrapper()
+ {
+ IBootstrapperDialog dialog = App.Settings.Prop.BootstrapperStyle.GetNew();
+ dialog.Message = "Style preview - Click Cancel to close";
+ dialog.CancelEnabled = true;
+ dialog.ShowBootstrapper();
+ }
+
public BootstrapperViewModel(Page page)
{