mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
commit
51dc149a56
@ -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");
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<ApplicationIcon>Bloxstrap.ico</ApplicationIcon>
|
||||
<Version>2.5.1</Version>
|
||||
<FileVersion>2.5.1.0</FileVersion>
|
||||
<Version>2.5.2</Version>
|
||||
<FileVersion>2.5.2.0</FileVersion>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -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");
|
||||
|
||||
@ -407,6 +406,9 @@ namespace Bloxstrap
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cancelFired)
|
||||
return;
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, "Cancelling install...");
|
||||
|
||||
_cancelTokenSource.Cancel();
|
||||
@ -508,45 +510,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,39 +578,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()
|
||||
@ -847,7 +848,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -980,7 +990,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;
|
||||
@ -1328,7 +1338,7 @@ 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);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -1352,6 +1362,9 @@ namespace Bloxstrap
|
||||
UpdateProgressBar();
|
||||
}
|
||||
|
||||
if (MD5Hash.FromStream(fileStream) != package.Signature)
|
||||
throw new Exception("Signature does not match!");
|
||||
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Finished downloading! ({totalBytesRead} bytes total)");
|
||||
break;
|
||||
}
|
||||
@ -1368,6 +1381,15 @@ namespace Bloxstrap
|
||||
|
||||
_totalDownloadedBytes -= totalBytesRead;
|
||||
UpdateProgressBar();
|
||||
|
||||
// attempt download over HTTP
|
||||
// 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://");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1406,17 +1428,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}");
|
||||
|
9
Bloxstrap/Enums/AssemblyLoadStatus.cs
Normal file
9
Bloxstrap/Enums/AssemblyLoadStatus.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Bloxstrap.Enums
|
||||
{
|
||||
enum AssemblyLoadStatus
|
||||
{
|
||||
NotAttempted,
|
||||
Failed,
|
||||
Successful
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
16
Bloxstrap/Exceptions/AssertionException.cs
Normal file
16
Bloxstrap/Exceptions/AssertionException.cs
Normal file
@ -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.")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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()!;
|
||||
}
|
||||
|
24
Bloxstrap/UI/Elements/Base/WpfUiWindow.cs
Normal file
24
Bloxstrap/UI/Elements/Base/WpfUiWindow.cs
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -10,7 +10,8 @@
|
||||
WindowStyle="None"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
AllowsTransparency="True"
|
||||
Background="Transparent">
|
||||
Background="Transparent"
|
||||
Closing="Window_Closing">
|
||||
<Border CornerRadius="10" BorderBrush="#33393B3D" Background="{Binding Background}" BorderThickness="{Binding DialogBorder}">
|
||||
<Grid>
|
||||
<Image Source="{Binding ByfronLogoLocation}" Width="114" Height="108" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="17,13,0,0" />
|
||||
|
@ -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
|
||||
|
@ -1,9 +1,10 @@
|
||||
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.Bootstrapper.FluentDialog"
|
||||
<base:WpfUiWindow x:Class="Bloxstrap.UI.Elements.Bootstrapper.FluentDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
|
||||
mc:Ignorable="d"
|
||||
Width="420"
|
||||
MinHeight="0"
|
||||
@ -12,7 +13,8 @@
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowBackdropType="Mica"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Closing="UiWindow_Closing">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@ -45,4 +47,4 @@
|
||||
<Button Margin="0" Content="Cancel" Width="120" HorizontalAlignment="Right" IsEnabled="{Binding CancelEnabled, Mode=OneWay}" Command="{Binding CancelInstallCommand}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</ui:UiWindow>
|
||||
</base:WpfUiWindow>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Windows.Forms;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Wpf.Ui.Appearance;
|
||||
using Wpf.Ui.Mvvm.Contracts;
|
||||
@ -14,12 +15,12 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
|
||||
/// </summary>
|
||||
public partial class FluentDialog : IBootstrapperDialog
|
||||
{
|
||||
private readonly IThemeService _themeService = new ThemeService();
|
||||
|
||||
private readonly BootstrapperDialogViewModel _viewModel;
|
||||
|
||||
public Bloxstrap.Bootstrapper? Bootstrapper { get; set; }
|
||||
|
||||
private bool _isClosing;
|
||||
|
||||
#region UI Elements
|
||||
public string Message
|
||||
{
|
||||
@ -66,22 +67,29 @@ 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)
|
||||
{
|
||||
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
|
||||
|
@ -30,61 +30,61 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
|
||||
/// </summary>
|
||||
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
|
||||
|
@ -1,4 +1,64 @@
|
||||
<root>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
@ -30,75 +30,75 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
|
||||
/// </summary>
|
||||
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
|
||||
|
@ -1,4 +1,64 @@
|
||||
<root>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
@ -30,93 +30,93 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
|
||||
/// </summary>
|
||||
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
|
||||
|
@ -1,4 +1,64 @@
|
||||
<root>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.ContextMenu.MenuContainer"
|
||||
<base:WpfUiWindow x:Class="Bloxstrap.UI.Elements.ContextMenu.MenuContainer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
|
||||
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
|
||||
mc:Ignorable="d"
|
||||
Title="ContextMenuContainer"
|
||||
MinWidth="0"
|
||||
@ -62,4 +63,4 @@
|
||||
<MenuItem x:Name="LogTracerMenuItem" Header="Open log tracer" Visibility="Collapsed" Click="LogTracerMenuItem_Click" />
|
||||
</ContextMenu>
|
||||
</ui:UiWindow.ContextMenu>
|
||||
</ui:UiWindow>
|
||||
</base:WpfUiWindow>
|
||||
|
@ -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,6 +30,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
|
||||
public MenuContainer(ActivityWatcher? activityWatcher, DiscordRichPresence? richPresenceHandler)
|
||||
{
|
||||
InitializeComponent();
|
||||
ApplyTheme();
|
||||
|
||||
_activityWatcher = activityWatcher;
|
||||
_richPresenceHandler = richPresenceHandler;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.Menu.MainWindow"
|
||||
<base:WpfUiWindow x:Class="Bloxstrap.UI.Elements.Menu.MainWindow"
|
||||
x:Name="ConfigurationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
@ -6,6 +6,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:pages="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
|
||||
mc:Ignorable="d"
|
||||
Title="Bloxstrap Menu"
|
||||
MinWidth="960"
|
||||
@ -79,4 +80,4 @@
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</ui:UiWindow>
|
||||
</base:WpfUiWindow>
|
||||
|
@ -14,21 +14,14 @@ namespace Bloxstrap.UI.Elements.Menu
|
||||
/// </summary>
|
||||
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");
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -4,25 +4,30 @@ 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)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
Bloxstrap/Utility/Shortcut.cs
Normal file
40
Bloxstrap/Utility/Shortcut.cs
Normal file
@ -0,0 +1,40 @@
|
||||
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 (FileNotFoundException ex)
|
||||
{
|
||||
App.Logger.WriteLine(LOG_IDENT, $"Failed to create a shortcut for {lnkPath}!");
|
||||
App.Logger.WriteException(LOG_IDENT, ex);
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user