From a9b3d43ab26af7f42e540c92f4aa7722475f2915 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Fri, 25 Aug 2023 23:25:08 +0100 Subject: [PATCH 01/13] Fix "access is denied" error I LOVE TESTING IN PROD --- Bloxstrap/Bootstrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 0302340..8ad6485 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -980,7 +980,7 @@ namespace Bloxstrap { const string LOG_IDENT = "Bootstrapper::ApplyModifications"; - if (Process.GetProcessesByName("RobloxPlayerBeta").Where(x => x.MainModule!.FileName == _playerLocation).Any()) + if (Process.GetProcessesByName("RobloxPlayerBeta").Any()) { App.Logger.WriteLine(LOG_IDENT, "Roblox is running, aborting mod check"); return; From af14c19334f0ef1cd322c066e7030426b6fb7565 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Fri, 25 Aug 2023 23:45:52 +0100 Subject: [PATCH 02/13] Catch exceptions when trying to delete a package --- Bloxstrap/Bootstrapper.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 8ad6485..7eee9be 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -847,7 +847,16 @@ namespace Bloxstrap if (!_versionPackageManifest.Exists(package => filename.Contains(package.Signature))) { App.Logger.WriteLine(LOG_IDENT, $"Deleting unused package {filename}"); - File.Delete(filename); + + try + { + File.Delete(filename); + } + catch (Exception ex) + { + App.Logger.WriteLine(LOG_IDENT, $"Failed to delete {filename}!"); + App.Logger.WriteException(LOG_IDENT, ex); + } } } From cd0547664c15a8de174c273419ed17da9905cd9e Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 00:05:18 +0100 Subject: [PATCH 03/13] Show better error message when auto-updating fails --- Bloxstrap/Bootstrapper.cs | 66 +++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 7eee9be..69dacdf 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -589,39 +589,51 @@ namespace Bloxstrap return; } - SetStatus($"Getting the latest {App.ProjectName}..."); - - // 64-bit is always the first option - GithubReleaseAsset asset = releaseInfo.Assets[0]; - string downloadLocation = Path.Combine(Paths.LocalAppData, "Temp", asset.Name); - - App.Logger.WriteLine(LOG_IDENT, $"Downloading {releaseInfo.TagName}..."); - - if (!File.Exists(downloadLocation)) + + try { - var response = await App.HttpClient.GetAsync(asset.BrowserDownloadUrl); + // 64-bit is always the first option + GithubReleaseAsset asset = releaseInfo.Assets[0]; + string downloadLocation = Path.Combine(Paths.LocalAppData, "Temp", asset.Name); - await using var fileStream = new FileStream(downloadLocation, FileMode.CreateNew); - await response.Content.CopyToAsync(fileStream); + App.Logger.WriteLine(LOG_IDENT, $"Downloading {releaseInfo.TagName}..."); + + if (!File.Exists(downloadLocation)) + { + var response = await App.HttpClient.GetAsync(asset.BrowserDownloadUrl); + + await using var fileStream = new FileStream(downloadLocation, FileMode.CreateNew); + await response.Content.CopyToAsync(fileStream); + } + + App.Logger.WriteLine(LOG_IDENT, $"Starting {releaseInfo.TagName}..."); + + ProcessStartInfo startInfo = new() + { + FileName = downloadLocation, + }; + + foreach (string arg in App.LaunchArgs) + startInfo.ArgumentList.Add(arg); + + App.Settings.Save(); + App.ShouldSaveConfigs = false; + + Process.Start(startInfo); + + App.Terminate(); } - - App.Logger.WriteLine(LOG_IDENT, $"Starting {releaseInfo.TagName}..."); - - ProcessStartInfo startInfo = new() + catch (Exception ex) { - FileName = downloadLocation, - }; + App.Logger.WriteLine(LOG_IDENT, "An exception occurred when running the auto-updater"); + App.Logger.WriteException(LOG_IDENT, ex); - foreach (string arg in App.LaunchArgs) - startInfo.ArgumentList.Add(arg); - - App.Settings.Save(); - App.ShouldSaveConfigs = false; - - Process.Start(startInfo); - - App.Terminate(); + Controls.ShowMessageBox( + $"Bloxstrap was unable to auto-update to {releaseInfo.TagName}. Please update it manually by downloading and running the latest release from the GitHub page.", + MessageBoxImage.Information + ); + } } private void Uninstall() From 034a51365033219a04bf519ec66619d58496e77d Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 00:34:58 +0100 Subject: [PATCH 04/13] Mitigate "decryption operation failed" error cant believe i only had this idea just now --- Bloxstrap/Bootstrapper.cs | 19 +++++++++++++++++- Bloxstrap/Utility/MD5Hash.cs | 37 +++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 69dacdf..4abd4e2 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -1349,7 +1349,10 @@ namespace Bloxstrap { var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token); await using var stream = await response.Content.ReadAsStreamAsync(_cancelTokenSource.Token); - await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew, FileAccess.Write, FileShare.Delete); + await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Delete); + + if (packageUrl.StartsWith("https://")) + throw new Exception("The decryption operation failed"); while (true) { @@ -1373,6 +1376,11 @@ namespace Bloxstrap UpdateProgressBar(); } + fileStream.Seek(0, SeekOrigin.Begin); + + if (MD5Hash.FromStream(fileStream) != package.Signature) + throw new Exception("Signature does not match!"); + App.Logger.WriteLine(LOG_IDENT, $"Finished downloading! ({totalBytesRead} bytes total)"); break; } @@ -1389,6 +1397,15 @@ namespace Bloxstrap _totalDownloadedBytes -= totalBytesRead; UpdateProgressBar(); + + // attempt download over HTTP + // this isn't actually that unsafe - signatures were established earlier over HTTPS + // so we've already established that our signatures are legit, and that there's no MITM anyway + if (ex.Message.Contains("The decryption operation failed")) + { + App.Logger.WriteLine(LOG_IDENT, "Retrying download over HTTP..."); + packageUrl = packageUrl.Replace("https://", "http://"); + } } } } diff --git a/Bloxstrap/Utility/MD5Hash.cs b/Bloxstrap/Utility/MD5Hash.cs index caa7e48..9b012cd 100644 --- a/Bloxstrap/Utility/MD5Hash.cs +++ b/Bloxstrap/Utility/MD5Hash.cs @@ -4,25 +4,28 @@ namespace Bloxstrap.Utility { public static class MD5Hash { - public static string FromFile(string filename) - { - using (MD5 md5 = MD5.Create()) - { - using (FileStream stream = File.OpenRead(filename)) - { - byte[] hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } - } - public static string FromBytes(byte[] data) { - using (MD5 md5 = MD5.Create()) - { - byte[] hash = md5.ComputeHash(data); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } + using MD5 md5 = MD5.Create(); + return Stringify(md5.ComputeHash(data)); + } + + public static string FromStream(Stream stream) + { + using MD5 md5 = MD5.Create(); + return Stringify(md5.ComputeHash(stream)); + } + + public static string FromFile(string filename) + { + using MD5 md5 = MD5.Create(); + using FileStream stream = File.OpenRead(filename); + return FromStream(stream); + } + + private static string Stringify(byte[] hash) + { + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } } } From 35253145cc04d99370e16d9034dbb09a0cc9be25 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 00:36:03 +0100 Subject: [PATCH 05/13] oops forgot to remove my test code --- Bloxstrap/Bootstrapper.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 4abd4e2..6f767e3 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -1351,9 +1351,6 @@ namespace Bloxstrap await using var stream = await response.Content.ReadAsStreamAsync(_cancelTokenSource.Token); await using var fileStream = new FileStream(packageLocation, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Delete); - if (packageUrl.StartsWith("https://")) - throw new Exception("The decryption operation failed"); - while (true) { if (_cancelFired) From 0df48408730e0dc7ecb6711d8ac28cb5deab0193 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 11:35:21 +0100 Subject: [PATCH 06/13] Make exception detection language agnostic mfw windows --- Bloxstrap/Bootstrapper.cs | 6 +++--- Bloxstrap/Enums/ErrorCode.cs | 5 ++++- Bloxstrap/Utilities.cs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 6f767e3..d192b25 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -1396,9 +1396,9 @@ namespace Bloxstrap UpdateProgressBar(); // attempt download over HTTP - // this isn't actually that unsafe - signatures were established earlier over HTTPS - // so we've already established that our signatures are legit, and that there's no MITM anyway - if (ex.Message.Contains("The decryption operation failed")) + // this isn't actually that unsafe - signatures were fetched earlier over HTTPS + // so we've already established that our signatures are legit, and that there's very likely no MITM anyway + if (ex.GetType() == typeof(IOException) && !packageUrl.StartsWith("http://")) { App.Logger.WriteLine(LOG_IDENT, "Retrying download over HTTP..."); packageUrl = packageUrl.Replace("https://", "http://"); diff --git a/Bloxstrap/Enums/ErrorCode.cs b/Bloxstrap/Enums/ErrorCode.cs index d9fbd42..ba6b65e 100644 --- a/Bloxstrap/Enums/ErrorCode.cs +++ b/Bloxstrap/Enums/ErrorCode.cs @@ -2,6 +2,7 @@ { // https://learn.microsoft.com/en-us/windows/win32/msi/error-codes // https://i-logic.com/serial/errorcodes.htm + // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/705fb797-2175-4a90-b5a3-3918024b10b8 // just the ones that we're interested in public enum ErrorCode @@ -9,6 +10,8 @@ ERROR_SUCCESS = 0, ERROR_INSTALL_USEREXIT = 1602, ERROR_INSTALL_FAILURE = 1603, - ERROR_CANCELLED = 1223 + ERROR_CANCELLED = 1223, + + CO_E_APPNOTFOUND = -2147221003 } } diff --git a/Bloxstrap/Utilities.cs b/Bloxstrap/Utilities.cs index 533928a..565dc79 100644 --- a/Bloxstrap/Utilities.cs +++ b/Bloxstrap/Utilities.cs @@ -18,7 +18,7 @@ namespace Bloxstrap { // lmfao - if (!ex.Message.Contains("Application not found")) + if (ex.NativeErrorCode != (int)ErrorCode.CO_E_APPNOTFOUND) throw; Process.Start(new ProcessStartInfo From 30ae3145378d21ce9d16d6a0452942b7ae67b957 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 14:49:06 +0100 Subject: [PATCH 07/13] Show notice if ShellLink can't be loaded --- Bloxstrap/App.xaml.cs | 2 +- Bloxstrap/Bootstrapper.cs | 38 ++++++++--------------- Bloxstrap/Enums/AssemblyLoadStatus.cs | 9 ++++++ Bloxstrap/Utility/Shortcut.cs | 43 +++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 27 deletions(-) create mode 100644 Bloxstrap/Enums/AssemblyLoadStatus.cs create mode 100644 Bloxstrap/Utility/Shortcut.cs diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index d760390..12b62fa 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -277,7 +277,7 @@ namespace Bloxstrap } } - Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t => + Task bootstrapperTask = Task.Run(async () => await bootstrapper.Run()).ContinueWith(t => { Logger.WriteLine(LOG_IDENT, "Bootstrapper task has finished"); diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index d192b25..2edd60e 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -52,7 +52,6 @@ namespace Bloxstrap private readonly CancellationTokenSource _cancelTokenSource = new(); private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid); - private static string DesktopShortcutLocation => Path.Combine(Paths.Desktop, "Play Roblox.lnk"); private string _playerLocation => Path.Combine(_versionFolder, "RobloxPlayerBeta.exe"); @@ -508,45 +507,32 @@ namespace Bloxstrap if (!Directory.Exists(Paths.StartMenu)) { Directory.CreateDirectory(Paths.StartMenu); - - ShellLink.Shortcut.CreateShortcut(Paths.Application, "", Paths.Application, 0) - .WriteToFile(Path.Combine(Paths.StartMenu, "Play Roblox.lnk")); - - ShellLink.Shortcut.CreateShortcut(Paths.Application, "-menu", Paths.Application, 0) - .WriteToFile(Path.Combine(Paths.StartMenu, $"{App.ProjectName} Menu.lnk")); } else { // v2.0.0 - rebadge configuration menu as just "Bloxstrap Menu" string oldMenuShortcut = Path.Combine(Paths.StartMenu, $"Configure {App.ProjectName}.lnk"); - string newMenuShortcut = Path.Combine(Paths.StartMenu, $"{App.ProjectName} Menu.lnk"); if (File.Exists(oldMenuShortcut)) File.Delete(oldMenuShortcut); - - if (!File.Exists(newMenuShortcut)) - ShellLink.Shortcut.CreateShortcut(Paths.Application, "-menu", Paths.Application, 0) - .WriteToFile(newMenuShortcut); } + Utility.Shortcut.Create(Paths.Application, "", Path.Combine(Paths.StartMenu, "Play Roblox.lnk")); + Utility.Shortcut.Create(Paths.Application, "-menu", Path.Combine(Paths.StartMenu, $"{App.ProjectName} Menu.lnk")); + if (App.Settings.Prop.CreateDesktopIcon) { - if (!File.Exists(DesktopShortcutLocation)) + try { - try - { - ShellLink.Shortcut.CreateShortcut(Paths.Application, "", Paths.Application, 0) - .WriteToFile(DesktopShortcutLocation); - } - catch (Exception ex) - { - App.Logger.WriteLine(LOG_IDENT, "Could not create desktop shortcut, aborting"); - App.Logger.WriteException(LOG_IDENT, ex); - } - } + Utility.Shortcut.Create(Paths.Application, "", Path.Combine(Paths.Desktop, "Play Roblox.lnk")); - // one-time toggle, set it back to false - App.Settings.Prop.CreateDesktopIcon = false; + // one-time toggle, set it back to false + App.Settings.Prop.CreateDesktopIcon = false; + } + catch (Exception) + { + // suppress, we likely just don't have write perms for the desktop folder + } } } diff --git a/Bloxstrap/Enums/AssemblyLoadStatus.cs b/Bloxstrap/Enums/AssemblyLoadStatus.cs new file mode 100644 index 0000000..08ef104 --- /dev/null +++ b/Bloxstrap/Enums/AssemblyLoadStatus.cs @@ -0,0 +1,9 @@ +namespace Bloxstrap.Enums +{ + enum AssemblyLoadStatus + { + NotAttempted, + Failed, + Successful + } +} diff --git a/Bloxstrap/Utility/Shortcut.cs b/Bloxstrap/Utility/Shortcut.cs new file mode 100644 index 0000000..1594a90 --- /dev/null +++ b/Bloxstrap/Utility/Shortcut.cs @@ -0,0 +1,43 @@ +using System.Windows; + +namespace Bloxstrap.Utility +{ + internal static class Shortcut + { + private static AssemblyLoadStatus _loadStatus = AssemblyLoadStatus.NotAttempted; + + public static void Create(string exePath, string exeArgs, string lnkPath) + { + const string LOG_IDENT = "Shortcut::Create"; + + if (File.Exists(lnkPath)) + return; + + try + { + ShellLink.Shortcut.CreateShortcut(exePath, exeArgs, exePath, 0).WriteToFile(lnkPath); + + if (_loadStatus != AssemblyLoadStatus.Successful) + _loadStatus = AssemblyLoadStatus.Successful; + } + catch (Exception ex) + { + App.Logger.WriteLine(LOG_IDENT, $"Failed to create a shortcut for {lnkPath}!"); + App.Logger.WriteException(LOG_IDENT, ex); + + if (ex.GetType() != typeof(FileNotFoundException)) + throw; + + if (_loadStatus == AssemblyLoadStatus.Failed) + return; + + _loadStatus = AssemblyLoadStatus.Failed; + + Controls.ShowMessageBox( + $"{App.ProjectName} was unable to create shortcuts for the Desktop and Start menu. They will be created the next time Roblox is launched.", + MessageBoxImage.Information + ); + } + } + } +} From dec04ecbd1715c4d1977b087a77df4b6caefb259 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 14:52:17 +0100 Subject: [PATCH 08/13] Bump version --- Bloxstrap/Bloxstrap.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Bloxstrap/Bloxstrap.csproj b/Bloxstrap/Bloxstrap.csproj index 48fc5dc..0b7d2f3 100644 --- a/Bloxstrap/Bloxstrap.csproj +++ b/Bloxstrap/Bloxstrap.csproj @@ -7,8 +7,8 @@ true True Bloxstrap.ico - 2.5.1 - 2.5.1.0 + 2.5.2 + 2.5.2.0 app.manifest From 1fda39bfb5e9de65cbde6a874050e2789594e825 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 14:57:52 +0100 Subject: [PATCH 09/13] i forgot you can do this --- Bloxstrap/Utility/Shortcut.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Bloxstrap/Utility/Shortcut.cs b/Bloxstrap/Utility/Shortcut.cs index 1594a90..efc8bc4 100644 --- a/Bloxstrap/Utility/Shortcut.cs +++ b/Bloxstrap/Utility/Shortcut.cs @@ -20,14 +20,11 @@ namespace Bloxstrap.Utility if (_loadStatus != AssemblyLoadStatus.Successful) _loadStatus = AssemblyLoadStatus.Successful; } - catch (Exception ex) + catch (FileNotFoundException ex) { App.Logger.WriteLine(LOG_IDENT, $"Failed to create a shortcut for {lnkPath}!"); App.Logger.WriteException(LOG_IDENT, ex); - if (ex.GetType() != typeof(FileNotFoundException)) - throw; - if (_loadStatus == AssemblyLoadStatus.Failed) return; From f5da33e92938c53eee6ccba93db5fb99db4ac1e7 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 15:44:42 +0100 Subject: [PATCH 10/13] Prevent redundant FFlag configuration logs --- Bloxstrap/FastFlagManager.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Bloxstrap/FastFlagManager.cs b/Bloxstrap/FastFlagManager.cs index 6f435b7..b3b94ea 100644 --- a/Bloxstrap/FastFlagManager.cs +++ b/Bloxstrap/FastFlagManager.cs @@ -140,9 +140,16 @@ namespace Bloxstrap else { if (Prop.ContainsKey(key)) + { + if (key == Prop[key].ToString()) + return; + App.Logger.WriteLine(LOG_IDENT, $"Changing of '{key}' from '{Prop[key]}' to '{value}' is pending"); + } else + { App.Logger.WriteLine(LOG_IDENT, $"Setting of '{key}' to '{value}' is pending"); + } Prop[key] = value.ToString()!; } From 199842547cf4d0bbb786102bb6d9d19e9407af41 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 16:21:59 +0100 Subject: [PATCH 11/13] Attempt to debug improper package extractions /shrug --- Bloxstrap/Bootstrapper.cs | 31 +++++++++++++++++----- Bloxstrap/Exceptions/AssertionException.cs | 16 +++++++++++ Bloxstrap/Utility/MD5Hash.cs | 2 ++ 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 Bloxstrap/Exceptions/AssertionException.cs diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 2edd60e..61c9365 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -1358,9 +1358,7 @@ namespace Bloxstrap _totalDownloadedBytes += bytesRead; UpdateProgressBar(); } - - fileStream.Seek(0, SeekOrigin.Begin); - + if (MD5Hash.FromStream(fileStream) != package.Signature) throw new Exception("Signature does not match!"); @@ -1427,17 +1425,36 @@ namespace Bloxstrap if (directory is not null) Directory.CreateDirectory(directory); + var fileManifest = _versionFileManifest.FirstOrDefault(x => x.Name == Path.Combine(PackageDirectories[package.Name], entry.FullName)); + string? signature = fileManifest?.Signature; + if (File.Exists(extractPath)) { - var fileManifest = _versionFileManifest.FirstOrDefault(x => x.Name == Path.Combine(PackageDirectories[package.Name], entry.FullName)); - - if (fileManifest is not null && MD5Hash.FromFile(extractPath) == fileManifest.Signature) + if (signature is not null && MD5Hash.FromFile(extractPath) == signature) continue; File.Delete(extractPath); } - entry.ExtractToFile(extractPath, true); + bool retry = false; + + do + { + using var entryStream = entry.Open(); + using var fileStream = new FileStream(extractPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize: 0x1000); + await entryStream.CopyToAsync(fileStream); + + if (signature is not null && MD5Hash.FromStream(fileStream) != signature) + { + if (retry) + throw new AssertionException($"Checksum of {entry.FullName} post-extraction did not match manifest"); + + retry = true; + } + } + while (retry); + + File.SetLastWriteTime(extractPath, entry.LastWriteTime.DateTime); } App.Logger.WriteLine(LOG_IDENT, $"Finished extracting {package.Name}"); diff --git a/Bloxstrap/Exceptions/AssertionException.cs b/Bloxstrap/Exceptions/AssertionException.cs new file mode 100644 index 0000000..5555baa --- /dev/null +++ b/Bloxstrap/Exceptions/AssertionException.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bloxstrap.Exceptions +{ + internal class AssertionException : Exception + { + public AssertionException(string message) + : base($"{message}\n\nThis is very likely just an off-chance error. Please report this first, and then start {App.ProjectName} again.") + { + } + } +} diff --git a/Bloxstrap/Utility/MD5Hash.cs b/Bloxstrap/Utility/MD5Hash.cs index 9b012cd..cec547d 100644 --- a/Bloxstrap/Utility/MD5Hash.cs +++ b/Bloxstrap/Utility/MD5Hash.cs @@ -12,6 +12,8 @@ namespace Bloxstrap.Utility public static string FromStream(Stream stream) { + stream.Seek(0, SeekOrigin.Begin); + using MD5 md5 = MD5.Create(); return Stringify(md5.ComputeHash(stream)); } From 0cca373833f4fbf87ba1bed6885cc61c72b1177f Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 19:39:57 +0100 Subject: [PATCH 12/13] Fix bug with launch closing not cancelling so apparently this is just a problem that has always existed lol --- Bloxstrap/Bootstrapper.cs | 3 + .../Bootstrapper/Base/WinFormsDialogBase.cs | 17 ++- .../Elements/Bootstrapper/ByfronDialog.xaml | 3 +- .../Bootstrapper/ByfronDialog.xaml.cs | 14 +- .../Elements/Bootstrapper/FluentDialog.xaml | 3 +- .../Bootstrapper/FluentDialog.xaml.cs | 18 ++- .../Bootstrapper/LegacyDialog2008.Designer.cs | 86 +++++------ .../Elements/Bootstrapper/LegacyDialog2008.cs | 16 +- .../Bootstrapper/LegacyDialog2008.resx | 62 +++++++- .../Bootstrapper/LegacyDialog2011.Designer.cs | 108 +++++++------- .../Elements/Bootstrapper/LegacyDialog2011.cs | 16 +- .../Bootstrapper/LegacyDialog2011.resx | 62 +++++++- .../Bootstrapper/ProgressDialog.Designer.cs | 138 +++++++++--------- .../Elements/Bootstrapper/ProgressDialog.resx | 62 +++++++- .../Bootstrapper/VistaDialog.Designer.cs | 1 + 15 files changed, 415 insertions(+), 194 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 61c9365..d68c50c 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -406,6 +406,9 @@ namespace Bloxstrap return; } + if (_cancelFired) + return; + App.Logger.WriteLine(LOG_IDENT, "Cancelling install..."); _cancelTokenSource.Cancel(); diff --git a/Bloxstrap/UI/Elements/Bootstrapper/Base/WinFormsDialogBase.cs b/Bloxstrap/UI/Elements/Bootstrapper/Base/WinFormsDialogBase.cs index ba14b07..69d4b36 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/Base/WinFormsDialogBase.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/Base/WinFormsDialogBase.cs @@ -8,6 +8,8 @@ namespace Bloxstrap.UI.Elements.Bootstrapper.Base { public Bloxstrap.Bootstrapper? Bootstrapper { get; set; } + private bool _isClosing; + #region UI Elements protected virtual string _message { get; set; } = "Please wait..."; protected virtual ProgressBarStyle _progressStyle { get; set; } @@ -81,11 +83,15 @@ namespace Bloxstrap.UI.Elements.Bootstrapper.Base Icon = App.Settings.Prop.BootstrapperIcon.GetIcon(); } - public void ButtonCancel_Click(object? sender, EventArgs e) + #region WinForms event handlers + public void ButtonCancel_Click(object? sender, EventArgs e) => Close(); + + public void Dialog_FormClosing(object sender, FormClosingEventArgs e) { - Bootstrapper?.CancelInstall(); - Close(); + if (!_isClosing) + Bootstrapper?.CancelInstall(); } + #endregion #region IBootstrapperDialog Methods public void ShowBootstrapper() => ShowDialog(); @@ -93,9 +99,14 @@ namespace Bloxstrap.UI.Elements.Bootstrapper.Base public virtual void CloseBootstrapper() { if (InvokeRequired) + { Invoke(CloseBootstrapper); + } else + { + _isClosing = true; Close(); + } } public virtual void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); diff --git a/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml b/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml index b2b9387..183be50 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml +++ b/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml @@ -10,7 +10,8 @@ WindowStyle="None" WindowStartupLocation="CenterScreen" AllowsTransparency="True" - Background="Transparent"> + Background="Transparent" + Closing="Window_Closing"> diff --git a/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml.cs b/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml.cs index 88020ad..b01d083 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/ByfronDialog.xaml.cs @@ -1,4 +1,5 @@ using System.Windows; +using System.ComponentModel; using System.Windows.Forms; using System.Windows.Media; using System.Windows.Media.Imaging; @@ -17,6 +18,8 @@ namespace Bloxstrap.UI.Elements.Bootstrapper public Bloxstrap.Bootstrapper? Bootstrapper { get; set; } + private bool _isClosing; + #region UI Elements public string Message { @@ -84,12 +87,21 @@ namespace Bloxstrap.UI.Elements.Bootstrapper InitializeComponent(); } + private void Window_Closing(object sender, CancelEventArgs e) + { + if (!_isClosing) + Bootstrapper?.CancelInstall(); + } #region IBootstrapperDialog Methods // Referencing FluentDialog public void ShowBootstrapper() => this.ShowDialog(); - public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); + public void CloseBootstrapper() + { + _isClosing = true; + Dispatcher.BeginInvoke(this.Close); + } public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); #endregion diff --git a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml index 374a823..5602e8c 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml +++ b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml @@ -12,7 +12,8 @@ Background="{ui:ThemeResource ApplicationBackgroundBrush}" ExtendsContentIntoTitleBar="True" WindowBackdropType="Mica" - WindowStartupLocation="CenterScreen"> + WindowStartupLocation="CenterScreen" + Closing="UiWindow_Closing"> diff --git a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs index d18776e..011a302 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs @@ -1,4 +1,5 @@ -using System.Windows.Forms; +using System.ComponentModel; +using System.Windows.Forms; using Wpf.Ui.Appearance; using Wpf.Ui.Mvvm.Contracts; @@ -20,6 +21,8 @@ namespace Bloxstrap.UI.Elements.Bootstrapper public Bloxstrap.Bootstrapper? Bootstrapper { get; set; } + private bool _isClosing; + #region UI Elements public string Message { @@ -77,11 +80,20 @@ namespace Bloxstrap.UI.Elements.Bootstrapper InitializeComponent(); } - #region IBootstrapperDialog Methods + private void UiWindow_Closing(object sender, CancelEventArgs e) + { + if (!_isClosing) + Bootstrapper?.CancelInstall(); + } + #region IBootstrapperDialog Methods public void ShowBootstrapper() => this.ShowDialog(); - public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); + public void CloseBootstrapper() + { + _isClosing = true; + Dispatcher.BeginInvoke(this.Close); + } public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); #endregion diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.Designer.cs b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.Designer.cs index 2da060a..28bc6c0 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.Designer.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.Designer.cs @@ -30,61 +30,61 @@ namespace Bloxstrap.UI.Elements.Bootstrapper /// private void InitializeComponent() { - this.labelMessage = new System.Windows.Forms.Label(); - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.SuspendLayout(); + labelMessage = new Label(); + ProgressBar = new ProgressBar(); + buttonCancel = new Button(); + SuspendLayout(); // // labelMessage // - this.labelMessage.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.labelMessage.Location = new System.Drawing.Point(12, 16); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(287, 17); - this.labelMessage.TabIndex = 0; - this.labelMessage.Text = "Please wait..."; + labelMessage.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + labelMessage.Location = new System.Drawing.Point(12, 16); + labelMessage.Name = "labelMessage"; + labelMessage.Size = new System.Drawing.Size(287, 17); + labelMessage.TabIndex = 0; + labelMessage.Text = "Please wait..."; // // ProgressBar // - this.ProgressBar.Location = new System.Drawing.Point(15, 47); - this.ProgressBar.MarqueeAnimationSpeed = 33; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(281, 20); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 1; + ProgressBar.Location = new System.Drawing.Point(15, 47); + ProgressBar.MarqueeAnimationSpeed = 33; + ProgressBar.Name = "ProgressBar"; + ProgressBar.Size = new System.Drawing.Size(281, 20); + ProgressBar.Style = ProgressBarStyle.Marquee; + ProgressBar.TabIndex = 1; // // buttonCancel // - this.buttonCancel.Enabled = false; - this.buttonCancel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.buttonCancel.Location = new System.Drawing.Point(221, 83); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(75, 23); - this.buttonCancel.TabIndex = 3; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); + buttonCancel.Enabled = false; + buttonCancel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + buttonCancel.Location = new System.Drawing.Point(221, 83); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new System.Drawing.Size(75, 23); + buttonCancel.TabIndex = 3; + buttonCancel.Text = "Cancel"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Click += ButtonCancel_Click; // // LegacyDialog2008 // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(311, 122); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.ProgressBar); - this.Controls.Add(this.labelMessage); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(327, 161); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(327, 161); - this.Name = "LegacyDialog2008"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "LegacyDialog2008"; - this.Load += new System.EventHandler(this.LegacyDialog2008_Load); - this.ResumeLayout(false); - + AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(311, 122); + Controls.Add(buttonCancel); + Controls.Add(ProgressBar); + Controls.Add(labelMessage); + Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + FormBorderStyle = FormBorderStyle.FixedSingle; + MaximizeBox = false; + MaximumSize = new System.Drawing.Size(327, 161); + MinimizeBox = false; + MinimumSize = new System.Drawing.Size(327, 161); + Name = "LegacyDialog2008"; + StartPosition = FormStartPosition.CenterScreen; + Text = "LegacyDialog2008"; + FormClosing += Dialog_FormClosing; + Load += LegacyDialog2008_Load; + ResumeLayout(false); } #endregion diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.cs b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.cs index 65d5251..ce2a1e8 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.cs @@ -9,10 +9,10 @@ namespace Bloxstrap.UI.Elements.Bootstrapper public partial class LegacyDialog2008 : WinFormsDialogBase { - protected override string _message - { - get => labelMessage.Text; - set => labelMessage.Text = value; + protected override string _message + { + get => labelMessage.Text; + set => labelMessage.Text = value; } protected override ProgressBarStyle _progressStyle @@ -27,10 +27,10 @@ namespace Bloxstrap.UI.Elements.Bootstrapper set => ProgressBar.Value = value; } - protected override bool _cancelEnabled - { - get => this.buttonCancel.Enabled; - set => this.buttonCancel.Enabled = value; + protected override bool _cancelEnabled + { + get => this.buttonCancel.Enabled; + set => this.buttonCancel.Enabled = value; } public LegacyDialog2008() diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.resx b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.resx index f298a7b..af32865 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.resx +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2008.resx @@ -1,4 +1,64 @@ - + + + diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.Designer.cs b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.Designer.cs index e970b64..51e76e7 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.Designer.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.Designer.cs @@ -30,75 +30,75 @@ namespace Bloxstrap.UI.Elements.Bootstrapper /// private void InitializeComponent() { - this.labelMessage = new System.Windows.Forms.Label(); - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.IconBox = new System.Windows.Forms.PictureBox(); - this.buttonCancel = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit(); - this.SuspendLayout(); + labelMessage = new Label(); + ProgressBar = new ProgressBar(); + IconBox = new PictureBox(); + buttonCancel = new Button(); + ((System.ComponentModel.ISupportInitialize)IconBox).BeginInit(); + SuspendLayout(); // // labelMessage // - this.labelMessage.Location = new System.Drawing.Point(55, 23); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(287, 17); - this.labelMessage.TabIndex = 0; - this.labelMessage.Text = "Please wait..."; + labelMessage.Location = new System.Drawing.Point(55, 23); + labelMessage.Name = "labelMessage"; + labelMessage.Size = new System.Drawing.Size(287, 17); + labelMessage.TabIndex = 0; + labelMessage.Text = "Please wait..."; // // ProgressBar // - this.ProgressBar.Location = new System.Drawing.Point(58, 51); - this.ProgressBar.MarqueeAnimationSpeed = 33; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(287, 26); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 1; + ProgressBar.Location = new System.Drawing.Point(58, 51); + ProgressBar.MarqueeAnimationSpeed = 33; + ProgressBar.Name = "ProgressBar"; + ProgressBar.Size = new System.Drawing.Size(287, 26); + ProgressBar.Style = ProgressBarStyle.Marquee; + ProgressBar.TabIndex = 1; // // IconBox // - this.IconBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.IconBox.ImageLocation = ""; - this.IconBox.Location = new System.Drawing.Point(19, 16); - this.IconBox.Name = "IconBox"; - this.IconBox.Size = new System.Drawing.Size(32, 32); - this.IconBox.TabIndex = 2; - this.IconBox.TabStop = false; + IconBox.BackgroundImageLayout = ImageLayout.Zoom; + IconBox.ImageLocation = ""; + IconBox.Location = new System.Drawing.Point(19, 16); + IconBox.Name = "IconBox"; + IconBox.Size = new System.Drawing.Size(32, 32); + IconBox.TabIndex = 2; + IconBox.TabStop = false; // // buttonCancel // - this.buttonCancel.Enabled = false; - this.buttonCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.buttonCancel.Location = new System.Drawing.Point(271, 83); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(75, 23); - this.buttonCancel.TabIndex = 3; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Visible = false; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); + buttonCancel.Enabled = false; + buttonCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + buttonCancel.Location = new System.Drawing.Point(271, 83); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new System.Drawing.Size(75, 23); + buttonCancel.TabIndex = 3; + buttonCancel.Text = "Cancel"; + buttonCancel.UseVisualStyleBackColor = true; + buttonCancel.Visible = false; + buttonCancel.Click += ButtonCancel_Click; // // LegacyDialog2011 // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(362, 131); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.IconBox); - this.Controls.Add(this.ProgressBar); - this.Controls.Add(this.labelMessage); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(378, 170); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(378, 170); - this.Name = "LegacyDialog2011"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "LegacyDialog2011"; - this.Load += new System.EventHandler(this.LegacyDialog2011_Load); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit(); - this.ResumeLayout(false); - + AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(362, 131); + Controls.Add(buttonCancel); + Controls.Add(IconBox); + Controls.Add(ProgressBar); + Controls.Add(labelMessage); + Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + FormBorderStyle = FormBorderStyle.FixedSingle; + MaximizeBox = false; + MaximumSize = new System.Drawing.Size(378, 170); + MinimizeBox = false; + MinimumSize = new System.Drawing.Size(378, 170); + Name = "LegacyDialog2011"; + StartPosition = FormStartPosition.CenterScreen; + Text = "LegacyDialog2011"; + FormClosing += Dialog_FormClosing; + Load += LegacyDialog2011_Load; + ((System.ComponentModel.ISupportInitialize)IconBox).EndInit(); + ResumeLayout(false); } #endregion diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.cs b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.cs index 0588675..5f92d4e 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.cs @@ -8,10 +8,10 @@ namespace Bloxstrap.UI.Elements.Bootstrapper public partial class LegacyDialog2011 : WinFormsDialogBase { - protected override string _message - { - get => labelMessage.Text; - set => labelMessage.Text = value; + protected override string _message + { + get => labelMessage.Text; + set => labelMessage.Text = value; } protected override ProgressBarStyle _progressStyle @@ -26,10 +26,10 @@ namespace Bloxstrap.UI.Elements.Bootstrapper set => ProgressBar.Value = value; } - protected override bool _cancelEnabled - { - get => this.buttonCancel.Enabled; - set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value; + protected override bool _cancelEnabled + { + get => this.buttonCancel.Enabled; + set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value; } public LegacyDialog2011() diff --git a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.resx b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.resx index f298a7b..af32865 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.resx +++ b/Bloxstrap/UI/Elements/Bootstrapper/LegacyDialog2011.resx @@ -1,4 +1,64 @@ - + + + diff --git a/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.Designer.cs b/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.Designer.cs index 2a76a62..066b8e5 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.Designer.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.Designer.cs @@ -30,93 +30,93 @@ namespace Bloxstrap.UI.Elements.Bootstrapper /// private void InitializeComponent() { - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.labelMessage = new System.Windows.Forms.Label(); - this.IconBox = new System.Windows.Forms.PictureBox(); - this.buttonCancel = new System.Windows.Forms.PictureBox(); - this.panel1 = new System.Windows.Forms.Panel(); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).BeginInit(); - this.panel1.SuspendLayout(); - this.SuspendLayout(); + ProgressBar = new ProgressBar(); + labelMessage = new Label(); + IconBox = new PictureBox(); + buttonCancel = new PictureBox(); + panel1 = new Panel(); + ((System.ComponentModel.ISupportInitialize)IconBox).BeginInit(); + ((System.ComponentModel.ISupportInitialize)buttonCancel).BeginInit(); + panel1.SuspendLayout(); + SuspendLayout(); // // ProgressBar // - this.ProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProgressBar.Location = new System.Drawing.Point(29, 241); - this.ProgressBar.MarqueeAnimationSpeed = 20; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(460, 20); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 0; + ProgressBar.Anchor = AnchorStyles.Left | AnchorStyles.Right; + ProgressBar.Location = new System.Drawing.Point(29, 241); + ProgressBar.MarqueeAnimationSpeed = 20; + ProgressBar.Name = "ProgressBar"; + ProgressBar.Size = new System.Drawing.Size(460, 20); + ProgressBar.Style = ProgressBarStyle.Marquee; + ProgressBar.TabIndex = 0; // // labelMessage // - this.labelMessage.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.labelMessage.Location = new System.Drawing.Point(29, 199); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(460, 18); - this.labelMessage.TabIndex = 1; - this.labelMessage.Text = "Please wait..."; - this.labelMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.labelMessage.UseMnemonic = false; + labelMessage.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + labelMessage.Location = new System.Drawing.Point(29, 199); + labelMessage.Name = "labelMessage"; + labelMessage.Size = new System.Drawing.Size(460, 18); + labelMessage.TabIndex = 1; + labelMessage.Text = "Please wait..."; + labelMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter; + labelMessage.UseMnemonic = false; // // IconBox // - this.IconBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.IconBox.ImageLocation = ""; - this.IconBox.Location = new System.Drawing.Point(212, 66); - this.IconBox.Name = "IconBox"; - this.IconBox.Size = new System.Drawing.Size(92, 92); - this.IconBox.TabIndex = 2; - this.IconBox.TabStop = false; + IconBox.BackgroundImageLayout = ImageLayout.Zoom; + IconBox.ImageLocation = ""; + IconBox.Location = new System.Drawing.Point(212, 66); + IconBox.Name = "IconBox"; + IconBox.Size = new System.Drawing.Size(92, 92); + IconBox.TabIndex = 2; + IconBox.TabStop = false; // // buttonCancel // - this.buttonCancel.Enabled = false; - this.buttonCancel.Image = global::Bloxstrap.Properties.Resources.CancelButton; - this.buttonCancel.Location = new System.Drawing.Point(194, 264); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(130, 44); - this.buttonCancel.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.buttonCancel.TabIndex = 3; - this.buttonCancel.TabStop = false; - this.buttonCancel.Visible = false; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); - this.buttonCancel.MouseEnter += new System.EventHandler(this.ButtonCancel_MouseEnter); - this.buttonCancel.MouseLeave += new System.EventHandler(this.ButtonCancel_MouseLeave); + buttonCancel.Enabled = false; + buttonCancel.Image = Properties.Resources.CancelButton; + buttonCancel.Location = new System.Drawing.Point(194, 264); + buttonCancel.Name = "buttonCancel"; + buttonCancel.Size = new System.Drawing.Size(130, 44); + buttonCancel.SizeMode = PictureBoxSizeMode.Zoom; + buttonCancel.TabIndex = 3; + buttonCancel.TabStop = false; + buttonCancel.Visible = false; + buttonCancel.Click += ButtonCancel_Click; + buttonCancel.MouseEnter += ButtonCancel_MouseEnter; + buttonCancel.MouseLeave += ButtonCancel_MouseLeave; // // panel1 // - this.panel1.BackColor = System.Drawing.SystemColors.Window; - this.panel1.Controls.Add(this.labelMessage); - this.panel1.Controls.Add(this.IconBox); - this.panel1.Controls.Add(this.buttonCancel); - this.panel1.Controls.Add(this.ProgressBar); - this.panel1.Location = new System.Drawing.Point(1, 1); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(518, 318); - this.panel1.TabIndex = 4; + panel1.BackColor = System.Drawing.SystemColors.Window; + panel1.Controls.Add(labelMessage); + panel1.Controls.Add(IconBox); + panel1.Controls.Add(buttonCancel); + panel1.Controls.Add(ProgressBar); + panel1.Location = new System.Drawing.Point(1, 1); + panel1.Name = "panel1"; + panel1.Size = new System.Drawing.Size(518, 318); + panel1.TabIndex = 4; // // ProgressDialog // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.ActiveBorder; - this.ClientSize = new System.Drawing.Size(520, 320); - this.Controls.Add(this.panel1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.MaximumSize = new System.Drawing.Size(520, 320); - this.MinimumSize = new System.Drawing.Size(520, 320); - this.Name = "ProgressDialog"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "ProgressDialog"; - this.Load += new System.EventHandler(this.ProgressDialog_Load); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).EndInit(); - this.panel1.ResumeLayout(false); - this.ResumeLayout(false); - + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = System.Drawing.SystemColors.ActiveBorder; + ClientSize = new System.Drawing.Size(520, 320); + Controls.Add(panel1); + FormBorderStyle = FormBorderStyle.None; + MaximumSize = new System.Drawing.Size(520, 320); + MinimumSize = new System.Drawing.Size(520, 320); + Name = "ProgressDialog"; + StartPosition = FormStartPosition.CenterScreen; + Text = "ProgressDialog"; + FormClosing += Dialog_FormClosing; + Load += ProgressDialog_Load; + ((System.ComponentModel.ISupportInitialize)IconBox).EndInit(); + ((System.ComponentModel.ISupportInitialize)buttonCancel).EndInit(); + panel1.ResumeLayout(false); + ResumeLayout(false); } #endregion diff --git a/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.resx b/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.resx index f298a7b..af32865 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.resx +++ b/Bloxstrap/UI/Elements/Bootstrapper/ProgressDialog.resx @@ -1,4 +1,64 @@ - + + + diff --git a/Bloxstrap/UI/Elements/Bootstrapper/VistaDialog.Designer.cs b/Bloxstrap/UI/Elements/Bootstrapper/VistaDialog.Designer.cs index 2d54c88..9f630d9 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/VistaDialog.Designer.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/VistaDialog.Designer.cs @@ -42,6 +42,7 @@ this.Text = "VistaDialog"; this.WindowState = System.Windows.Forms.FormWindowState.Minimized; this.Load += new System.EventHandler(this.VistaDialog_Load); + this.FormClosing += this.Dialog_FormClosing; this.ResumeLayout(false); } From 197429dbf936b791d0472f474c0eb9349eb6f0ed Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 26 Aug 2023 20:52:56 +0100 Subject: [PATCH 13/13] Fix theme not applying to notification area menu --- Bloxstrap/UI/Elements/Base/WpfUiWindow.cs | 24 +++++++++++++++++++ .../Elements/Bootstrapper/FluentDialog.xaml | 5 ++-- .../Bootstrapper/FluentDialog.xaml.cs | 10 +++----- .../Elements/ContextMenu/MenuContainer.xaml | 5 ++-- .../ContextMenu/MenuContainer.xaml.cs | 7 +++++- Bloxstrap/UI/Elements/Menu/MainWindow.xaml | 5 ++-- Bloxstrap/UI/Elements/Menu/MainWindow.xaml.cs | 13 +++------- .../UI/ViewModels/Menu/AppearanceViewModel.cs | 2 +- 8 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 Bloxstrap/UI/Elements/Base/WpfUiWindow.cs diff --git a/Bloxstrap/UI/Elements/Base/WpfUiWindow.cs b/Bloxstrap/UI/Elements/Base/WpfUiWindow.cs new file mode 100644 index 0000000..d941ea8 --- /dev/null +++ b/Bloxstrap/UI/Elements/Base/WpfUiWindow.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Wpf.Ui.Appearance; +using Wpf.Ui.Controls; +using Wpf.Ui.Mvvm.Contracts; +using Wpf.Ui.Mvvm.Services; + +namespace Bloxstrap.UI.Elements.Base +{ + public class WpfUiWindow : UiWindow + { + private readonly IThemeService _themeService = new ThemeService(); + + public void ApplyTheme() + { + _themeService.SetTheme(App.Settings.Prop.Theme.GetFinal() == Enums.Theme.Dark ? ThemeType.Dark : ThemeType.Light); + _themeService.SetSystemAccent(); + } + } +} diff --git a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml index 5602e8c..40cc7f9 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml +++ b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml @@ -1,9 +1,10 @@ - - + diff --git a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs index 011a302..7ab6cdc 100644 --- a/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs +++ b/Bloxstrap/UI/Elements/Bootstrapper/FluentDialog.xaml.cs @@ -15,8 +15,6 @@ namespace Bloxstrap.UI.Elements.Bootstrapper /// public partial class FluentDialog : IBootstrapperDialog { - private readonly IThemeService _themeService = new ThemeService(); - private readonly BootstrapperDialogViewModel _viewModel; public Bloxstrap.Bootstrapper? Bootstrapper { get; set; } @@ -69,15 +67,13 @@ namespace Bloxstrap.UI.Elements.Bootstrapper public FluentDialog() { + InitializeComponent(); + ApplyTheme(); + _viewModel = new FluentDialogViewModel(this); DataContext = _viewModel; Title = App.Settings.Prop.BootstrapperTitle; Icon = App.Settings.Prop.BootstrapperIcon.GetIcon().GetImageSource(); - - _themeService.SetTheme(App.Settings.Prop.Theme.GetFinal() == Enums.Theme.Dark ? ThemeType.Dark : ThemeType.Light); - _themeService.SetSystemAccent(); - - InitializeComponent(); } private void UiWindow_Closing(object sender, CancelEventArgs e) diff --git a/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml b/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml index d2ad043..58d48b3 100644 --- a/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml +++ b/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml @@ -1,10 +1,11 @@ - - + diff --git a/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml.cs b/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml.cs index 8354ced..f2b8df0 100644 --- a/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml.cs +++ b/Bloxstrap/UI/Elements/ContextMenu/MenuContainer.xaml.cs @@ -2,6 +2,10 @@ using System.Windows.Controls; using System.Windows.Interop; +using Wpf.Ui.Appearance; +using Wpf.Ui.Mvvm.Contracts; +using Wpf.Ui.Mvvm.Services; + using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.UI.WindowsAndMessaging; @@ -26,7 +30,8 @@ namespace Bloxstrap.UI.Elements.ContextMenu public MenuContainer(ActivityWatcher? activityWatcher, DiscordRichPresence? richPresenceHandler) { InitializeComponent(); - + ApplyTheme(); + _activityWatcher = activityWatcher; _richPresenceHandler = richPresenceHandler; diff --git a/Bloxstrap/UI/Elements/Menu/MainWindow.xaml b/Bloxstrap/UI/Elements/Menu/MainWindow.xaml index 6fee20e..2a00fdd 100644 --- a/Bloxstrap/UI/Elements/Menu/MainWindow.xaml +++ b/Bloxstrap/UI/Elements/Menu/MainWindow.xaml @@ -1,4 +1,4 @@ - - + diff --git a/Bloxstrap/UI/Elements/Menu/MainWindow.xaml.cs b/Bloxstrap/UI/Elements/Menu/MainWindow.xaml.cs index 968dabf..2c748f9 100644 --- a/Bloxstrap/UI/Elements/Menu/MainWindow.xaml.cs +++ b/Bloxstrap/UI/Elements/Menu/MainWindow.xaml.cs @@ -14,21 +14,14 @@ namespace Bloxstrap.UI.Elements.Menu /// public partial class MainWindow : INavigationWindow { - private readonly IThemeService _themeService = new ThemeService(); - public MainWindow() { + InitializeComponent(); + ApplyTheme(); + App.Logger.WriteLine("MainWindow::MainWindow", "Initializing menu"); DataContext = new MainWindowViewModel(this); - SetTheme(); - InitializeComponent(); - } - - public void SetTheme() - { - _themeService.SetTheme(App.Settings.Prop.Theme.GetFinal() == Enums.Theme.Dark ? ThemeType.Dark : ThemeType.Light); - _themeService.SetSystemAccent(); } public void OpenWiki(object? sender, EventArgs e) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki"); diff --git a/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs b/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs index cb81afa..9f8a453 100644 --- a/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs +++ b/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs @@ -63,7 +63,7 @@ namespace Bloxstrap.UI.ViewModels.Menu set { App.Settings.Prop.Theme = Themes[value]; - ((MainWindow)Window.GetWindow(_page)!).SetTheme(); + ((MainWindow)Window.GetWindow(_page)!).ApplyTheme(); } }