From 7d72c47de021645ec5bd2eb32b75abdcf127509a Mon Sep 17 00:00:00 2001 From: CodingWonders <101426328+CodingWonders@users.noreply.github.com> Date: Sun, 11 Oct 2026 11:57:17 +0200 Subject: [PATCH 1/5] Update assembly information --- MicroWin/AppState.cs | 2 +- MicroWin/MainForm.cs | 2 +- MicroWin/MicroWin.csproj | 4 ++-- MicroWin/Properties/AssemblyInfo.cs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MicroWin/AppState.cs b/MicroWin/AppState.cs index ffeb810..fd854ae 100755 --- a/MicroWin/AppState.cs +++ b/MicroWin/AppState.cs @@ -25,6 +25,6 @@ public static class AppState public static string? SaveISO { get; set; } public static string? WinUtilConfigPath { get; set; } - public static string Version => "v2.0"; + public static string Version => "v2.1"; } } \ No newline at end of file diff --git a/MicroWin/MainForm.cs b/MicroWin/MainForm.cs index ffc6c04..cecce31 100755 --- a/MicroWin/MainForm.cs +++ b/MicroWin/MainForm.cs @@ -34,7 +34,7 @@ namespace MicroWin public partial class MainForm : Form { private const string swStatus = "stable"; - private const string appVer = "2.0.1"; + private const string appVer = "2.1"; private WizardPage CurrentWizardPage = new(); private List VerifyInPages = [ diff --git a/MicroWin/MicroWin.csproj b/MicroWin/MicroWin.csproj index a5f5e3c..9612a4e 100755 --- a/MicroWin/MicroWin.csproj +++ b/MicroWin/MicroWin.csproj @@ -14,8 +14,8 @@ false logo.ico - 2.0.1.0 - 2.0.1.0 + 2.1.0.0 + 2.1.0.0 diff --git a/MicroWin/Properties/AssemblyInfo.cs b/MicroWin/Properties/AssemblyInfo.cs index ef87a42..c7b55b9 100755 --- a/MicroWin/Properties/AssemblyInfo.cs +++ b/MicroWin/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("2.0.1.0")] -[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] From c3400eac46c79a1517b151a74bc9c0ebf75bc14f Mon Sep 17 00:00:00 2001 From: CodingWonders <101426328+CodingWonders@users.noreply.github.com> Date: Sun, 11 Oct 2026 12:03:24 +0200 Subject: [PATCH 2/5] Add quotes to OSCDIMG boot data string Fixes #51 --- MicroWin/functions/OSCDIMG/OscdimgUtilities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs b/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs index 432a4e7..9166ea7 100644 --- a/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs +++ b/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs @@ -78,7 +78,7 @@ private static void InvokeOscdimg(Action? actionReporter = null, Action efisysPath = Path.Combine(efiBootBinsPath, "efisys.bin"), efisysExPath = Path.Combine(efiBootBinsPath, "efisys_EX.bin"); - string bootDataString = $"2#p0,e,b{etfsbootPath}#pEF,e,b{(UEFICA23Bins && File.Exists(efisysExPath) ? efisysExPath : efisysPath)}"; + string bootDataString = $"2#p0,e,b\"{etfsbootPath}\"#pEF,e,b\"{(UEFICA23Bins && File.Exists(efisysExPath) ? efisysExPath : efisysPath)}\""; // Start the ISO building Process oscdimgProc = new Process() From 5a9487a8c5ff7d3048ca137f5685fa13a66e5266 Mon Sep 17 00:00:00 2001 From: CodingWonders <101426328+CodingWonders@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:16:26 +0200 Subject: [PATCH 3/5] Add regional support (#54) * Add regional support * Add version identifier * Add some logging --- MicroWin/AppState.cs | 3 + MicroWin/Classes/Regional/GeoId.cs | 45 ++ MicroWin/Classes/Regional/ImageLanguage.cs | 50 ++ .../Classes/Regional/KeyboardIdentifier.cs | 65 ++ MicroWin/Classes/Regional/TimeOffset.cs | 55 ++ MicroWin/Classes/Regional/UserLocale.cs | 63 ++ MicroWin/MainForm.Designer.cs | 487 ++++++++----- MicroWin/MainForm.cs | 128 +++- MicroWin/MainForm.resx | 10 +- MicroWin/MicroWin.csproj | 13 + MicroWin/Resources/Regional/GeoId.xml | 270 +++++++ MicroWin/Resources/Regional/ImageLanguage.xml | 41 ++ .../Resources/Regional/KeyboardIdentifier.xml | 246 +++++++ MicroWin/Resources/Regional/TimeOffset.xml | 142 ++++ MicroWin/Resources/Regional/UserLocale.xml | 689 ++++++++++++++++++ .../ProgramResources/ResourceHelper.cs | 21 + .../functions/OSCDIMG/OscdimgUtilities.cs | 4 +- MicroWin/functions/dism/UnattendGenerator.cs | 63 ++ VERSION | 1 + 19 files changed, 2213 insertions(+), 183 deletions(-) create mode 100644 MicroWin/Classes/Regional/GeoId.cs create mode 100644 MicroWin/Classes/Regional/ImageLanguage.cs create mode 100644 MicroWin/Classes/Regional/KeyboardIdentifier.cs create mode 100644 MicroWin/Classes/Regional/TimeOffset.cs create mode 100644 MicroWin/Classes/Regional/UserLocale.cs create mode 100644 MicroWin/Resources/Regional/GeoId.xml create mode 100644 MicroWin/Resources/Regional/ImageLanguage.xml create mode 100644 MicroWin/Resources/Regional/KeyboardIdentifier.xml create mode 100644 MicroWin/Resources/Regional/TimeOffset.xml create mode 100644 MicroWin/Resources/Regional/UserLocale.xml create mode 100644 MicroWin/functions/Helpers/ProgramResources/ResourceHelper.cs create mode 100644 VERSION diff --git a/MicroWin/AppState.cs b/MicroWin/AppState.cs index fd854ae..76c9ae1 100755 --- a/MicroWin/AppState.cs +++ b/MicroWin/AppState.cs @@ -1,4 +1,5 @@ using MicroWin.Classes; +using MicroWin.Classes.Regional; using System.Collections.Generic; using System.IO; @@ -24,6 +25,8 @@ public static class AppState public static bool UseUEFICA23Bins { get; set; } = true; public static string? SaveISO { get; set; } public static string? WinUtilConfigPath { get; set; } + public static UserLocale? userLocale { get; set; } + public static TimeOffset? timeOffset { get; set; } public static string Version => "v2.1"; } diff --git a/MicroWin/Classes/Regional/GeoId.cs b/MicroWin/Classes/Regional/GeoId.cs new file mode 100644 index 0000000..f3528ff --- /dev/null +++ b/MicroWin/Classes/Regional/GeoId.cs @@ -0,0 +1,45 @@ +using MicroWin.functions.Helpers.ProgramResources; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace MicroWin.Classes.Regional +{ + public class GeoId + { + [XmlAttribute("Id")] + public required string Id; + + [XmlAttribute("DisplayName")] + public required string DisplayName; + + public override string ToString() { + return $"GeoID {Id} -- {DisplayName}"; + } + + public static List LoadItems() { + List geoList = []; + + try { + XmlReaderSettings xs = new() { IgnoreWhitespace = true }; +#pragma warning disable CS8604 + using XmlReader reader = XmlReader.Create(ResourceHelper.GetProgramResourceStream("MicroWin.Resources.Regional.GeoId.xml"), xs); +#pragma warning restore CS8604 + while (reader.Read()) { + if (reader.NodeType == XmlNodeType.Element && reader.Name == "GeoId") { + geoList.Add(new() { Id = reader.GetAttribute("Id") ?? "", DisplayName = reader.GetAttribute("DisplayName") ?? "" }); + } + } + } catch (Exception ex) { + if (Debugger.IsAttached) + Debugger.Break(); + Debug.WriteLine(ex.Message); + } + + return geoList; + } + } +} diff --git a/MicroWin/Classes/Regional/ImageLanguage.cs b/MicroWin/Classes/Regional/ImageLanguage.cs new file mode 100644 index 0000000..c2c59c8 --- /dev/null +++ b/MicroWin/Classes/Regional/ImageLanguage.cs @@ -0,0 +1,50 @@ +using MicroWin.functions.Helpers.ProgramResources; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace MicroWin.Classes.Regional +{ + public class ImageLanguage + { + [XmlAttribute("Id")] + public required string Id; + + [XmlAttribute("DisplayName")] + public required string DisplayName; + + public override string ToString() { + return $"Language {Id} -- {DisplayName}"; + } + + public static List LoadItems() { + List langList = []; + + try + { + XmlReaderSettings xs = new() { IgnoreWhitespace = true }; +#pragma warning disable CS8604 + using XmlReader reader = XmlReader.Create(ResourceHelper.GetProgramResourceStream("MicroWin.Resources.Regional.ImageLanguage.xml"), xs); +#pragma warning restore CS8604 + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element && reader.Name == "ImageLanguage") + { + langList.Add(new() { Id = reader.GetAttribute("Id") ?? "", DisplayName = reader.GetAttribute("DisplayName") ?? "" }); + } + } + } + catch (Exception ex) + { + if (Debugger.IsAttached) + Debugger.Break(); + Debug.WriteLine(ex.Message); + } + + return langList; + } + } +} diff --git a/MicroWin/Classes/Regional/KeyboardIdentifier.cs b/MicroWin/Classes/Regional/KeyboardIdentifier.cs new file mode 100644 index 0000000..84d045d --- /dev/null +++ b/MicroWin/Classes/Regional/KeyboardIdentifier.cs @@ -0,0 +1,65 @@ +using MicroWin.functions.Helpers.ProgramResources; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; + +namespace MicroWin.Classes.Regional +{ + public class KeyboardIdentifier + { + + public required string Id; + + public required string DisplayName; + + public required string TypeString; + + public KeyboardType GetKeyboardType() + { + return TypeString switch + { + "Keyboard" => KeyboardType.Keyboard, + "IME" => KeyboardType.IME, + _ => KeyboardType.Unknown + }; + } + + public override string ToString() { + return $"Keyboard {Id} -- {DisplayName} -- {GetKeyboardType()}"; + } + + public static List LoadItems() { + List keyboardList = []; + + try + { + XmlReaderSettings xs = new() { IgnoreWhitespace = true }; +#pragma warning disable CS8604 + using XmlReader reader = XmlReader.Create(ResourceHelper.GetProgramResourceStream("MicroWin.Resources.Regional.KeyboardIdentifier.xml"), xs); +#pragma warning restore CS8604 + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element && reader.Name == "KeyboardIdentifier") + { + keyboardList.Add(new() { Id = reader.GetAttribute("Id") ?? "", DisplayName = reader.GetAttribute("DisplayName") ?? "", TypeString = reader.GetAttribute("Type") ?? "" }); + } + } + } + catch (Exception ex) + { + if (Debugger.IsAttached) + Debugger.Break(); + Debug.WriteLine(ex.Message); + } + return keyboardList; + } + } + + public enum KeyboardType : int { + Unknown = -1, + Keyboard = 0, + IME = 1 + } +} diff --git a/MicroWin/Classes/Regional/TimeOffset.cs b/MicroWin/Classes/Regional/TimeOffset.cs new file mode 100644 index 0000000..6a2ded0 --- /dev/null +++ b/MicroWin/Classes/Regional/TimeOffset.cs @@ -0,0 +1,55 @@ +using MicroWin.functions.Helpers.ProgramResources; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace MicroWin.Classes.Regional +{ + public class TimeOffset + { + [XmlAttribute("Id")] + public required string Id; + + [XmlAttribute("DisplayName")] + public required string DisplayName; + + public override string ToString() { + return $"Time Offset {Id} -- {DisplayName}"; + } + + public static List LoadItems() { + List offsetList = []; + + try + { + XmlReaderSettings xs = new() { IgnoreWhitespace = true }; +#pragma warning disable CS8604 + using XmlReader reader = XmlReader.Create(ResourceHelper.GetProgramResourceStream("MicroWin.Resources.Regional.TimeOffset.xml"), xs); +#pragma warning restore CS8604 + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element && reader.Name == "TimeOffset") + { + offsetList.Add(new() { Id = reader.GetAttribute("Id") ?? "", DisplayName = reader.GetAttribute("DisplayName") ?? "" }); + } + } + } + catch (Exception ex) + { + if (Debugger.IsAttached) + Debugger.Break(); + Debug.WriteLine(ex.Message); + } + + return offsetList; + } + + public TimeOffset Clone() + { + return (TimeOffset)MemberwiseClone(); + } + } +} diff --git a/MicroWin/Classes/Regional/UserLocale.cs b/MicroWin/Classes/Regional/UserLocale.cs new file mode 100644 index 0000000..38bd212 --- /dev/null +++ b/MicroWin/Classes/Regional/UserLocale.cs @@ -0,0 +1,63 @@ +using MicroWin.functions.Helpers.ProgramResources; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace MicroWin.Classes.Regional +{ + public class UserLocale + { + [XmlAttribute("Id")] + public required string Id; + [XmlAttribute("DisplayName")] + public required string DisplayName; + [XmlAttribute("LCID")] + public required string LCID; + [XmlAttribute("KeyboardLayout")] + public string? KeyboardLayout; + [XmlAttribute("GeoLocation")] + public string? GeoLocation; + + public override string ToString() + { + return $"User Locale {Id} -- {DisplayName} -- {LCID} -- {KeyboardLayout} -- {GeoLocation}"; + } + + public UserLocale Clone() { + return (UserLocale)MemberwiseClone(); + } + + public static List LoadItems() { + List localeList = []; + + try + { + XmlReaderSettings xs = new() { IgnoreWhitespace = true }; +#pragma warning disable CS8604 + using XmlReader reader = XmlReader.Create(ResourceHelper.GetProgramResourceStream("MicroWin.Resources.Regional.UserLocale.xml"), xs); +#pragma warning restore CS8604 + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element && reader.Name == "UserLocale") + { + localeList.Add(new() { Id = reader.GetAttribute("Id") ?? "", DisplayName = reader.GetAttribute("DisplayName") ?? "", + LCID = reader.GetAttribute("LCID") ?? "", KeyboardLayout = reader.GetAttribute("KeyboardLayout") ?? "", + GeoLocation = reader.GetAttribute("GeoLocation") ?? "" }); + } + } + } + catch (Exception ex) + { + if (Debugger.IsAttached) + Debugger.Break(); + Debug.WriteLine(ex.Message); + } + + return localeList; + } + + } +} diff --git a/MicroWin/MainForm.Designer.cs b/MicroWin/MainForm.Designer.cs index f377d50..abe24a9 100755 --- a/MicroWin/MainForm.Designer.cs +++ b/MicroWin/MainForm.Designer.cs @@ -36,6 +36,30 @@ private void InitializeComponent() Cancel_Button = new Button(); About_Button = new Button(); PageContainerPanel = new Panel(); + IsoSettingsPage = new Panel(); + label19 = new Label(); + UEFICA23CB = new CheckBox(); + DriverExportCombo = new ComboBox(); + label13 = new Label(); + UnattendCopyCB = new CheckBox(); + ReportToolCB = new CheckBox(); + label11 = new Label(); + label12 = new Label(); + winutilConfigLabel = new Label(); + winutilConfigTextBox = new TextBox(); + winutilConfigBrowseBtn = new Button(); + CopyVirtIODrivers = new CheckBox(); + gbRegionalOptions = new GroupBox(); + tableLayoutPanel4 = new TableLayoutPanel(); + comboOffset = new ComboBox(); + label24 = new Label(); + label23 = new Label(); + label22 = new Label(); + label21 = new Label(); + comboTimeFormat = new ComboBox(); + comboIme = new ComboBox(); + comboRegion = new ComboBox(); + label20 = new Label(); FinishPage = new Panel(); lnkViewCreationLogs = new LinkLabel(); lnkOpenIsoLoc = new LinkLabel(); @@ -54,19 +78,6 @@ private void InitializeComponent() logTB = new TextBox(); label14 = new Label(); label15 = new Label(); - IsoSettingsPage = new Panel(); - label19 = new Label(); - UEFICA23CB = new CheckBox(); - DriverExportCombo = new ComboBox(); - label13 = new Label(); - UnattendCopyCB = new CheckBox(); - ReportToolCB = new CheckBox(); - label11 = new Label(); - label12 = new Label(); - winutilConfigLabel = new Label(); - winutilConfigTextBox = new TextBox(); - winutilConfigBrowseBtn = new Button(); - CopyVirtIODrivers = new CheckBox(); UserAccountsPage = new Panel(); panel1 = new Panel(); tableLayoutPanel3 = new TableLayoutPanel(); @@ -118,11 +129,13 @@ private void InitializeComponent() ButtonPanel.SuspendLayout(); TableLayoutPanel1.SuspendLayout(); PageContainerPanel.SuspendLayout(); + IsoSettingsPage.SuspendLayout(); + gbRegionalOptions.SuspendLayout(); + tableLayoutPanel4.SuspendLayout(); FinishPage.SuspendLayout(); panel4.SuspendLayout(); IsoCreationPage.SuspendLayout(); pnlProgress.SuspendLayout(); - IsoSettingsPage.SuspendLayout(); UserAccountsPage.SuspendLayout(); panel1.SuspendLayout(); tableLayoutPanel3.SuspendLayout(); @@ -214,9 +227,9 @@ private void InitializeComponent() // // PageContainerPanel // + PageContainerPanel.Controls.Add(IsoSettingsPage); PageContainerPanel.Controls.Add(FinishPage); PageContainerPanel.Controls.Add(IsoCreationPage); - PageContainerPanel.Controls.Add(IsoSettingsPage); PageContainerPanel.Controls.Add(UserAccountsPage); PageContainerPanel.Controls.Add(ImageChooserPage); PageContainerPanel.Controls.Add(IsoChooserPage); @@ -228,6 +241,284 @@ private void InitializeComponent() PageContainerPanel.Size = new Size(1264, 641); PageContainerPanel.TabIndex = 3; // + // IsoSettingsPage + // + IsoSettingsPage.Controls.Add(label19); + IsoSettingsPage.Controls.Add(UEFICA23CB); + IsoSettingsPage.Controls.Add(DriverExportCombo); + IsoSettingsPage.Controls.Add(label13); + IsoSettingsPage.Controls.Add(UnattendCopyCB); + IsoSettingsPage.Controls.Add(ReportToolCB); + IsoSettingsPage.Controls.Add(label11); + IsoSettingsPage.Controls.Add(label12); + IsoSettingsPage.Controls.Add(winutilConfigLabel); + IsoSettingsPage.Controls.Add(winutilConfigTextBox); + IsoSettingsPage.Controls.Add(winutilConfigBrowseBtn); + IsoSettingsPage.Controls.Add(CopyVirtIODrivers); + IsoSettingsPage.Controls.Add(gbRegionalOptions); + IsoSettingsPage.Dock = DockStyle.Fill; + IsoSettingsPage.Location = new Point(0, 0); + IsoSettingsPage.Name = "IsoSettingsPage"; + IsoSettingsPage.Size = new Size(1264, 641); + IsoSettingsPage.TabIndex = 6; + // + // label19 + // + label19.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + label19.AutoEllipsis = true; + label19.Location = new Point(101, 504); + label19.Name = "label19"; + label19.Size = new Size(1084, 89); + label19.TabIndex = 14; + label19.Text = resources.GetString("label19.Text"); + label19.Visible = false; + // + // UEFICA23CB + // + UEFICA23CB.AutoSize = true; + UEFICA23CB.Checked = true; + UEFICA23CB.CheckState = CheckState.Checked; + UEFICA23CB.Location = new Point(83, 399); + UEFICA23CB.Name = "UEFICA23CB"; + UEFICA23CB.Size = new Size(380, 19); + UEFICA23CB.TabIndex = 10; + UEFICA23CB.Text = "Use Windows UEFI CA 2023 boot binaries, if available on the ISO file"; + UEFICA23CB.UseVisualStyleBackColor = true; + UEFICA23CB.CheckedChanged += UEFICA23CB_CheckedChanged; + // + // DriverExportCombo + // + DriverExportCombo.FormattingEnabled = true; + DriverExportCombo.Items.AddRange(new object[] { "Don't export drivers", "Export essential drivers (Storage Controllers and Network Adapters)", "Export all drivers" }); + DriverExportCombo.Location = new Point(83, 370); + DriverExportCombo.Name = "DriverExportCombo"; + DriverExportCombo.Size = new Size(412, 23); + DriverExportCombo.TabIndex = 9; + DriverExportCombo.SelectedIndexChanged += DriverExportCombo_SelectedIndexChanged; + // + // label13 + // + label13.AutoSize = true; + label13.Location = new Point(80, 349); + label13.Name = "label13"; + label13.Size = new Size(111, 15); + label13.TabIndex = 8; + label13.Text = "Driver export mode:"; + // + // UnattendCopyCB + // + UnattendCopyCB.AutoSize = true; + UnattendCopyCB.Location = new Point(83, 322); + UnattendCopyCB.Name = "UnattendCopyCB"; + UnattendCopyCB.Size = new Size(412, 19); + UnattendCopyCB.TabIndex = 7; + UnattendCopyCB.Text = "Make a copy of the unattended answer file that I can use on other images"; + UnattendCopyCB.UseVisualStyleBackColor = true; + UnattendCopyCB.CheckedChanged += UnattendCopyCB_CheckedChanged; + // + // ReportToolCB + // + ReportToolCB.AutoSize = true; + ReportToolCB.Checked = true; + ReportToolCB.CheckState = CheckState.Checked; + ReportToolCB.Location = new Point(83, 297); + ReportToolCB.Name = "ReportToolCB"; + ReportToolCB.Size = new Size(218, 19); + ReportToolCB.TabIndex = 7; + ReportToolCB.Text = "Add a shortcut for the reporting tool"; + ReportToolCB.UseVisualStyleBackColor = true; + ReportToolCB.CheckedChanged += ReportToolCB_CheckedChanged; + // + // label11 + // + label11.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label11.AutoEllipsis = true; + label11.Location = new Point(17, 64); + label11.Name = "label11"; + label11.Size = new Size(1233, 52); + label11.TabIndex = 6; + label11.Text = "Configure additional settings for your customized image."; + // + // label12 + // + label12.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label12.AutoEllipsis = true; + label12.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); + label12.Location = new Point(14, 12); + label12.Name = "label12"; + label12.Size = new Size(1236, 45); + label12.TabIndex = 5; + label12.Text = "Specify additional settings for the image"; + // + // winutilConfigLabel + // + winutilConfigLabel.AutoSize = true; + winutilConfigLabel.Location = new Point(80, 429); + winutilConfigLabel.Name = "winutilConfigLabel"; + winutilConfigLabel.Size = new Size(127, 15); + winutilConfigLabel.TabIndex = 11; + winutilConfigLabel.Text = "WinUtil Config (JSON):"; + // + // winutilConfigTextBox + // + winutilConfigTextBox.Location = new Point(83, 450); + winutilConfigTextBox.Name = "winutilConfigTextBox"; + winutilConfigTextBox.Size = new Size(293, 23); + winutilConfigTextBox.TabIndex = 12; + winutilConfigTextBox.TextChanged += winutilConfigTextBox_TextChanged; + // + // winutilConfigBrowseBtn + // + winutilConfigBrowseBtn.FlatStyle = FlatStyle.System; + winutilConfigBrowseBtn.Location = new Point(382, 449); + winutilConfigBrowseBtn.Name = "winutilConfigBrowseBtn"; + winutilConfigBrowseBtn.Size = new Size(80, 23); + winutilConfigBrowseBtn.TabIndex = 13; + winutilConfigBrowseBtn.Text = "Browse..."; + winutilConfigBrowseBtn.UseVisualStyleBackColor = true; + winutilConfigBrowseBtn.Click += winutilConfigBrowseBtn_Click; + // + // CopyVirtIODrivers + // + CopyVirtIODrivers.AutoSize = true; + CopyVirtIODrivers.Location = new Point(83, 482); + CopyVirtIODrivers.Name = "CopyVirtIODrivers"; + CopyVirtIODrivers.Size = new Size(125, 19); + CopyVirtIODrivers.TabIndex = 7; + CopyVirtIODrivers.Text = "Copy VirtIO drivers"; + CopyVirtIODrivers.UseVisualStyleBackColor = true; + CopyVirtIODrivers.CheckedChanged += CopyVirtIODrivers_CheckedChanged; + // + // gbRegionalOptions + // + gbRegionalOptions.Controls.Add(tableLayoutPanel4); + gbRegionalOptions.Controls.Add(label20); + gbRegionalOptions.Location = new Point(80, 133); + gbRegionalOptions.Name = "gbRegionalOptions"; + gbRegionalOptions.Size = new Size(738, 158); + gbRegionalOptions.TabIndex = 15; + gbRegionalOptions.TabStop = false; + gbRegionalOptions.Text = "Regional Settings"; + // + // tableLayoutPanel4 + // + tableLayoutPanel4.ColumnCount = 2; + tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 23.2240429F)); + tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 76.7759552F)); + tableLayoutPanel4.Controls.Add(comboOffset, 1, 3); + tableLayoutPanel4.Controls.Add(label24, 0, 3); + tableLayoutPanel4.Controls.Add(label23, 0, 2); + tableLayoutPanel4.Controls.Add(label22, 0, 1); + tableLayoutPanel4.Controls.Add(label21, 0, 0); + tableLayoutPanel4.Controls.Add(comboTimeFormat, 1, 0); + tableLayoutPanel4.Controls.Add(comboIme, 1, 1); + tableLayoutPanel4.Controls.Add(comboRegion, 1, 2); + tableLayoutPanel4.Dock = DockStyle.Fill; + tableLayoutPanel4.Location = new Point(3, 42); + tableLayoutPanel4.Name = "tableLayoutPanel4"; + tableLayoutPanel4.RowCount = 4; + tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); + tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); + tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); + tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); + tableLayoutPanel4.Size = new Size(732, 113); + tableLayoutPanel4.TabIndex = 1; + // + // comboOffset + // + comboOffset.Dock = DockStyle.Fill; + comboOffset.FormattingEnabled = true; + comboOffset.Location = new Point(173, 87); + comboOffset.Name = "comboOffset"; + comboOffset.Size = new Size(556, 23); + comboOffset.TabIndex = 6; + comboOffset.SelectedIndexChanged += comboOffset_SelectedIndexChanged; + // + // label24 + // + label24.AutoSize = true; + label24.Dock = DockStyle.Fill; + label24.Location = new Point(3, 84); + label24.Name = "label24"; + label24.Size = new Size(164, 29); + label24.TabIndex = 5; + label24.Text = "Time zone:"; + label24.TextAlign = ContentAlignment.MiddleLeft; + // + // label23 + // + label23.AutoSize = true; + label23.Dock = DockStyle.Fill; + label23.Location = new Point(3, 56); + label23.Name = "label23"; + label23.Size = new Size(164, 28); + label23.TabIndex = 3; + label23.Text = "Region:"; + label23.TextAlign = ContentAlignment.MiddleLeft; + // + // label22 + // + label22.AutoSize = true; + label22.Dock = DockStyle.Fill; + label22.Location = new Point(3, 28); + label22.Name = "label22"; + label22.Size = new Size(164, 28); + label22.TabIndex = 2; + label22.Text = "Keyboard or input method:"; + label22.TextAlign = ContentAlignment.MiddleLeft; + // + // label21 + // + label21.AutoSize = true; + label21.Dock = DockStyle.Fill; + label21.Location = new Point(3, 0); + label21.Name = "label21"; + label21.Size = new Size(164, 28); + label21.TabIndex = 1; + label21.Text = "Time and currency format:"; + label21.TextAlign = ContentAlignment.MiddleLeft; + // + // comboTimeFormat + // + comboTimeFormat.Dock = DockStyle.Fill; + comboTimeFormat.FormattingEnabled = true; + comboTimeFormat.Location = new Point(173, 3); + comboTimeFormat.Name = "comboTimeFormat"; + comboTimeFormat.Size = new Size(556, 23); + comboTimeFormat.TabIndex = 4; + comboTimeFormat.SelectedIndexChanged += comboTimeFormat_SelectedIndexChanged; + // + // comboIme + // + comboIme.Dock = DockStyle.Fill; + comboIme.FormattingEnabled = true; + comboIme.Location = new Point(173, 31); + comboIme.Name = "comboIme"; + comboIme.Size = new Size(556, 23); + comboIme.TabIndex = 4; + comboIme.SelectedIndexChanged += comboIme_SelectedIndexChanged; + // + // comboRegion + // + comboRegion.Dock = DockStyle.Fill; + comboRegion.FormattingEnabled = true; + comboRegion.Location = new Point(173, 59); + comboRegion.Name = "comboRegion"; + comboRegion.Size = new Size(556, 23); + comboRegion.TabIndex = 4; + comboRegion.SelectedIndexChanged += comboRegion_SelectedIndexChanged; + // + // label20 + // + label20.AutoSize = true; + label20.Dock = DockStyle.Top; + label20.Location = new Point(3, 19); + label20.Name = "label20"; + label20.Padding = new Padding(4); + label20.Size = new Size(648, 23); + label20.TabIndex = 0; + label20.Text = "Configure the regional options for the target system. You can change these after the operating system finishes installing."; + // // FinishPage // FinishPage.Controls.Add(lnkViewCreationLogs); @@ -434,153 +725,6 @@ private void InitializeComponent() label15.TabIndex = 7; label15.Text = "Customizations in progress"; // - // IsoSettingsPage - // - IsoSettingsPage.Controls.Add(label19); - IsoSettingsPage.Controls.Add(UEFICA23CB); - IsoSettingsPage.Controls.Add(DriverExportCombo); - IsoSettingsPage.Controls.Add(label13); - IsoSettingsPage.Controls.Add(UnattendCopyCB); - IsoSettingsPage.Controls.Add(ReportToolCB); - IsoSettingsPage.Controls.Add(label11); - IsoSettingsPage.Controls.Add(label12); - IsoSettingsPage.Controls.Add(winutilConfigLabel); - IsoSettingsPage.Controls.Add(winutilConfigTextBox); - IsoSettingsPage.Controls.Add(winutilConfigBrowseBtn); - IsoSettingsPage.Controls.Add(CopyVirtIODrivers); - IsoSettingsPage.Dock = DockStyle.Fill; - IsoSettingsPage.Location = new Point(0, 0); - IsoSettingsPage.Name = "IsoSettingsPage"; - IsoSettingsPage.Size = new Size(1264, 641); - IsoSettingsPage.TabIndex = 6; - // - // label19 - // - label19.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - label19.AutoEllipsis = true; - label19.Location = new Point(101, 340); - label19.Name = "label19"; - label19.Size = new Size(1062, 243); - label19.TabIndex = 14; - label19.Text = resources.GetString("label19.Text"); - label19.Visible = false; - // - // UEFICA23CB - // - UEFICA23CB.AutoSize = true; - UEFICA23CB.Checked = true; - UEFICA23CB.CheckState = CheckState.Checked; - UEFICA23CB.Location = new Point(83, 235); - UEFICA23CB.Name = "UEFICA23CB"; - UEFICA23CB.Size = new Size(380, 19); - UEFICA23CB.TabIndex = 10; - UEFICA23CB.Text = "Use Windows UEFI CA 2023 boot binaries, if available on the ISO file"; - UEFICA23CB.UseVisualStyleBackColor = true; - UEFICA23CB.CheckedChanged += UEFICA23CB_CheckedChanged; - // - // DriverExportCombo - // - DriverExportCombo.FormattingEnabled = true; - DriverExportCombo.Items.AddRange(new object[] { "Don't export drivers", "Export essential drivers (Storage Controllers and Network Adapters)", "Export all drivers" }); - DriverExportCombo.Location = new Point(83, 206); - DriverExportCombo.Name = "DriverExportCombo"; - DriverExportCombo.Size = new Size(412, 23); - DriverExportCombo.TabIndex = 9; - DriverExportCombo.SelectedIndexChanged += DriverExportCombo_SelectedIndexChanged; - // - // label13 - // - label13.AutoSize = true; - label13.Location = new Point(80, 185); - label13.Name = "label13"; - label13.Size = new Size(111, 15); - label13.TabIndex = 8; - label13.Text = "Driver export mode:"; - // - // UnattendCopyCB - // - UnattendCopyCB.AutoSize = true; - UnattendCopyCB.Location = new Point(83, 158); - UnattendCopyCB.Name = "UnattendCopyCB"; - UnattendCopyCB.Size = new Size(412, 19); - UnattendCopyCB.TabIndex = 7; - UnattendCopyCB.Text = "Make a copy of the unattended answer file that I can use on other images"; - UnattendCopyCB.UseVisualStyleBackColor = true; - UnattendCopyCB.CheckedChanged += UnattendCopyCB_CheckedChanged; - // - // ReportToolCB - // - ReportToolCB.AutoSize = true; - ReportToolCB.Checked = true; - ReportToolCB.CheckState = CheckState.Checked; - ReportToolCB.Location = new Point(83, 133); - ReportToolCB.Name = "ReportToolCB"; - ReportToolCB.Size = new Size(218, 19); - ReportToolCB.TabIndex = 7; - ReportToolCB.Text = "Add a shortcut for the reporting tool"; - ReportToolCB.UseVisualStyleBackColor = true; - ReportToolCB.CheckedChanged += ReportToolCB_CheckedChanged; - // - // label11 - // - label11.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label11.AutoEllipsis = true; - label11.Location = new Point(17, 64); - label11.Name = "label11"; - label11.Size = new Size(1233, 52); - label11.TabIndex = 6; - label11.Text = "Configure additional settings for your customized image."; - // - // label12 - // - label12.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label12.AutoEllipsis = true; - label12.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); - label12.Location = new Point(14, 12); - label12.Name = "label12"; - label12.Size = new Size(1236, 45); - label12.TabIndex = 5; - label12.Text = "Specify additional settings for the image"; - // - // winutilConfigLabel - // - winutilConfigLabel.AutoSize = true; - winutilConfigLabel.Location = new Point(80, 265); - winutilConfigLabel.Name = "winutilConfigLabel"; - winutilConfigLabel.Size = new Size(127, 15); - winutilConfigLabel.TabIndex = 11; - winutilConfigLabel.Text = "WinUtil Config (JSON):"; - // - // winutilConfigTextBox - // - winutilConfigTextBox.Location = new Point(83, 286); - winutilConfigTextBox.Name = "winutilConfigTextBox"; - winutilConfigTextBox.Size = new Size(293, 23); - winutilConfigTextBox.TabIndex = 12; - winutilConfigTextBox.TextChanged += winutilConfigTextBox_TextChanged; - // - // winutilConfigBrowseBtn - // - winutilConfigBrowseBtn.FlatStyle = FlatStyle.System; - winutilConfigBrowseBtn.Location = new Point(382, 285); - winutilConfigBrowseBtn.Name = "winutilConfigBrowseBtn"; - winutilConfigBrowseBtn.Size = new Size(80, 23); - winutilConfigBrowseBtn.TabIndex = 13; - winutilConfigBrowseBtn.Text = "Browse..."; - winutilConfigBrowseBtn.UseVisualStyleBackColor = true; - winutilConfigBrowseBtn.Click += winutilConfigBrowseBtn_Click; - // - // CopyVirtIODrivers - // - CopyVirtIODrivers.AutoSize = true; - CopyVirtIODrivers.Location = new Point(83, 318); - CopyVirtIODrivers.Name = "CopyVirtIODrivers"; - CopyVirtIODrivers.Size = new Size(125, 19); - CopyVirtIODrivers.TabIndex = 7; - CopyVirtIODrivers.Text = "Copy VirtIO drivers"; - CopyVirtIODrivers.UseVisualStyleBackColor = true; - CopyVirtIODrivers.CheckedChanged += CopyVirtIODrivers_CheckedChanged; - // // UserAccountsPage // UserAccountsPage.Controls.Add(panel1); @@ -1101,6 +1245,12 @@ private void InitializeComponent() ButtonPanel.ResumeLayout(false); TableLayoutPanel1.ResumeLayout(false); PageContainerPanel.ResumeLayout(false); + IsoSettingsPage.ResumeLayout(false); + IsoSettingsPage.PerformLayout(); + gbRegionalOptions.ResumeLayout(false); + gbRegionalOptions.PerformLayout(); + tableLayoutPanel4.ResumeLayout(false); + tableLayoutPanel4.PerformLayout(); FinishPage.ResumeLayout(false); FinishPage.PerformLayout(); panel4.ResumeLayout(false); @@ -1109,8 +1259,6 @@ private void InitializeComponent() IsoCreationPage.PerformLayout(); pnlProgress.ResumeLayout(false); pnlProgress.PerformLayout(); - IsoSettingsPage.ResumeLayout(false); - IsoSettingsPage.PerformLayout(); UserAccountsPage.ResumeLayout(false); UserAccountsPage.PerformLayout(); panel1.ResumeLayout(false); @@ -1220,5 +1368,16 @@ private void InitializeComponent() private CheckBox UEFICA23CB; internal Label label19; private ColumnHeader columnHeader4; + private GroupBox gbRegionalOptions; + private TableLayoutPanel tableLayoutPanel4; + private Label label20; + private ComboBox comboOffset; + private Label label24; + private Label label23; + private Label label22; + private Label label21; + private ComboBox comboTimeFormat; + private ComboBox comboIme; + private ComboBox comboRegion; } } diff --git a/MicroWin/MainForm.cs b/MicroWin/MainForm.cs index cecce31..b6cd3d9 100755 --- a/MicroWin/MainForm.cs +++ b/MicroWin/MainForm.cs @@ -1,12 +1,14 @@ using Microsoft.Dism; using Microsoft.Win32; using MicroWin.Classes; +using MicroWin.Classes.Regional; using MicroWin.functions.dism; using MicroWin.functions.Helpers.DeleteFile; using MicroWin.functions.Helpers.DesktopWindowManager; using MicroWin.functions.Helpers.DriverHelpers; using MicroWin.functions.Helpers.Loggers; using MicroWin.functions.Helpers.PowerManagement; +using MicroWin.functions.Helpers.ProgramResources; using MicroWin.functions.Helpers.PropertyCheckers; using MicroWin.functions.Helpers.RegistryHelpers; using MicroWin.functions.Helpers.WMI; @@ -50,6 +52,19 @@ public partial class MainForm : Form private bool isEsdFile = false; + // REGIONAL SETTINGS + private List geoIds = []; + private List imageLanguages = []; + private List keyboardIdentifiers = []; + private List timeOffsets = []; + private List userLocales = []; + + private static readonly UserLocale defaultLocale = new() { Id = "en-US", DisplayName = "English (United States)", LCID = "0409", KeyboardLayout = "00000409", GeoLocation = "244" }; + private static UserLocale finalLocale = defaultLocale.Clone(); + private static TimeOffset defaultOffset = new() { Id = "UTC", DisplayName = "(UTC) Coordinated Universal Time" }; + private static TimeOffset finalOffset = defaultOffset.Clone(); + + public MainForm() { InitializeComponent(); @@ -87,6 +102,15 @@ private void SetColorMode() logTB.ForeColor = ForeColor; winutilConfigTextBox.BackColor = BackColor; winutilConfigTextBox.ForeColor = ForeColor; + gbRegionalOptions.ForeColor = ForeColor; + comboOffset.BackColor = BackColor; + comboOffset.ForeColor = ForeColor; + comboIme.BackColor = BackColor; + comboIme.ForeColor = ForeColor; + comboTimeFormat.BackColor = BackColor; + comboTimeFormat.ForeColor = ForeColor; + comboRegion.BackColor = BackColor; + comboRegion.ForeColor = ForeColor; WindowHelper.ToggleDarkTitleBar(Handle, colorVal == 0); } @@ -163,27 +187,33 @@ private bool VerifyOptionsInPage(WizardPage.Page wizardPage) } #pragma warning disable CS8602 - if (VersionComparer.IsOlderThanVersion(imageInfo.ElementAtOrDefault(AppState.SelectedImageIndex - 1 ?? 0).ProductVersion, VersionComparer.VERCONST_WIN10)) { + if (VersionComparer.IsOlderThanVersion(imageInfo.ElementAtOrDefault(AppState.SelectedImageIndex - 1 ?? 0).ProductVersion, VersionComparer.VERCONST_WIN10)) + { MessageBox.Show("Windows images containing Windows 10 1809 or earlier are not supported."); return false; } #pragma warning restore CS8602 // If we are in ESD mode, we'll begin the export procedure - if (isEsdFile) { + if (isEsdFile) + { string sourceEsd = Path.Combine(AppState.MountPath, "sources", "install.esd"), destinationWim = Path.Combine(AppState.MountPath, "sources", "install.wim"); MessageBox.Show("Your Windows image will be converted to an editable format.", Text, MessageBoxButtons.OK, MessageBoxIcon.Information); - if (!DismManager.ExportImage(sourceEsd, AppState.SelectedImageIndex, destinationWim, "max")) { + if (!DismManager.ExportImage(sourceEsd, AppState.SelectedImageIndex, destinationWim, "max")) + { MessageBox.Show("Your Windows image could not be converted to an editable format.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } - try { + try + { File.Delete(sourceEsd); - } catch { + } + catch + { string cmdProcPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "cmd.exe"), takeownPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "takeown.exe"), icaclsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "icacls.exe"); @@ -292,6 +322,33 @@ private void MainForm_Load(object sender, EventArgs e) columnHeader4.Width = WindowHelper.ScaleLogical(128); columnHeader5.Width = WindowHelper.ScaleLogical(84); columnHeader6.Width = WindowHelper.ScaleLogical(160); + + // Load regional settings + geoIds = GeoId.LoadItems().OrderBy(entry => entry.DisplayName).ToList(); + imageLanguages = ImageLanguage.LoadItems().OrderBy(entry => entry.DisplayName).ToList(); + keyboardIdentifiers = KeyboardIdentifier.LoadItems().OrderBy(entry => entry.DisplayName).ToList(); + timeOffsets = TimeOffset.LoadItems().OrderBy(entry => entry.DisplayName).ToList(); + userLocales = UserLocale.LoadItems().OrderBy(entry => entry.DisplayName).ToList(); + + comboTimeFormat.Items.AddRange(userLocales.Select(locale => locale.DisplayName).ToArray()); + comboIme.Items.AddRange(keyboardIdentifiers.Select(keyboard => $"{keyboard.DisplayName}{(keyboard.GetKeyboardType() == KeyboardType.IME ? " (IME)" : "")}").ToArray()); + comboRegion.Items.AddRange(geoIds.Select(geoId => geoId.DisplayName).ToArray()); + comboOffset.Items.AddRange(timeOffsets.Select(offset => offset.DisplayName).ToArray()); + + try + { + comboTimeFormat.SelectedItem = defaultLocale.DisplayName; + comboIme.SelectedItem = keyboardIdentifiers.FirstOrDefault(kbd => kbd.Id == defaultLocale.KeyboardLayout)?.DisplayName; + comboRegion.SelectedItem = geoIds.FirstOrDefault(geoId => geoId.Id == defaultLocale.GeoLocation)?.DisplayName; + comboOffset.SelectedItem = "(UTC) Coordinated Universal Time"; + } + catch + { + + } + + AppState.userLocale = finalLocale.Clone(); + AppState.timeOffset = finalOffset.Clone(); } @@ -370,7 +427,8 @@ private void LoadWimData() if (File.Exists(wimPath)) { - if (Path.GetExtension(wimPath).EndsWith("esd", StringComparison.OrdinalIgnoreCase)) { + if (Path.GetExtension(wimPath).EndsWith("esd", StringComparison.OrdinalIgnoreCase)) + { // ESD files require that we export them first to WIM. This will be done later, // because we'll be able to know the index. isEsdFile = true; @@ -777,7 +835,9 @@ await Task.Run(() => } }); } - } catch { + } + catch + { WriteLogMessage("Could not download VirtIO drivers..."); } } @@ -851,16 +911,18 @@ await Task.Run(() => { // Check if we can do it using the embedded resource; otherwise grab it from the internet. string firstStartupPath = Path.Combine(AppState.ScratchPath, "Windows", "FirstStartup.ps1"); - try { - Assembly currentAssembly = Assembly.GetExecutingAssembly(); - using Stream resourceStream = currentAssembly.GetManifestResourceStream("MicroWin.tools.FirstStartup.ps1"); + try + { + using Stream resourceStream = ResourceHelper.GetProgramResourceStream("MicroWin.tools.FirstStartup.ps1"); if (resourceStream is null) throw new Exception(); using StreamReader sr = new(resourceStream); string firstRunScriptContents = sr.ReadToEnd(); File.WriteAllText(firstStartupPath, firstRunScriptContents, new UTF8Encoding(false)); - } catch { + } + catch + { DynaLog.logMessage("Could not get embedded res. Downloading from internet."); using HttpClient client = new(); byte[] data = client.GetByteArrayAsync("https://github.com/CodingWonders/MicroWin/raw/main/MicroWin/tools/FirstStartup.ps1").GetAwaiter().GetResult(); @@ -978,7 +1040,8 @@ await Task.Run(() => RegistryHelper.UnloadRegistryHive("zDEFAULT"); RegistryHelper.UnloadRegistryHive("zNTUSER"); - if (Directory.Exists(bootDriverPath)) { + if (Directory.Exists(bootDriverPath)) + { UpdateCurrentStatus("Installing system drivers..."); DriverInstallHelper.InstallDrivers(AppState.ScratchPath, bootDriverPath, (message) => WriteLogMessage(message)); } @@ -1167,5 +1230,46 @@ private void Cancel_Button_Click(object sender, EventArgs e) { Close(); } + + private void comboTimeFormat_SelectedIndexChanged(object sender, EventArgs e) + { + // Reselect the locale + UserLocale selectedLocale = userLocales[comboTimeFormat.SelectedIndex]; + int keyboardLayoutIndex = keyboardIdentifiers.FindIndex(keybId => keybId.Id == selectedLocale.KeyboardLayout); + int geoIdIndex = geoIds.FindIndex(geoId => geoId.Id == selectedLocale.GeoLocation); + finalLocale = selectedLocale.Clone(); + +#nullable disable + comboIme.SelectedIndexChanged -= comboIme_SelectedIndexChanged; + comboRegion.SelectedIndexChanged -= comboRegion_SelectedIndexChanged; + if (keyboardLayoutIndex > -1) comboIme.SelectedIndex = keyboardLayoutIndex; + if (geoIdIndex > -1) comboRegion.SelectedIndex = geoIdIndex; + comboIme.SelectedIndexChanged += comboIme_SelectedIndexChanged; + comboRegion.SelectedIndexChanged += comboRegion_SelectedIndexChanged; + + // set user preferences + finalLocale.GeoLocation = geoIds[comboRegion.SelectedIndex].Id; + finalLocale.KeyboardLayout = keyboardIdentifiers[comboIme.SelectedIndex].Id; +#nullable restore + AppState.userLocale = finalLocale.Clone(); + } + + private void comboIme_SelectedIndexChanged(object sender, EventArgs e) + { + finalLocale.KeyboardLayout = keyboardIdentifiers[comboIme.SelectedIndex].Id; + AppState.userLocale = finalLocale.Clone(); + } + + private void comboRegion_SelectedIndexChanged(object sender, EventArgs e) + { + finalLocale.GeoLocation = geoIds[comboRegion.SelectedIndex].Id; + AppState.userLocale = finalLocale.Clone(); + } + + private void comboOffset_SelectedIndexChanged(object sender, EventArgs e) + { + finalOffset = timeOffsets[comboOffset.SelectedIndex].Clone(); + AppState.timeOffset = finalOffset.Clone(); + } } } diff --git a/MicroWin/MainForm.resx b/MicroWin/MainForm.resx index b0a6ead..f6568f5 100644 --- a/MicroWin/MainForm.resx +++ b/MicroWin/MainForm.resx @@ -117,17 +117,17 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - To continue with OS installation, use a tool to create bootable USB drives, such as Rufus or Ventoy, and install the system. - -If you want to continue customizing this system, use either of the following: - To proceed with installation of the MicroWin image in QEMU/Proxmox VE: 1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives 2. Click "Load Driver" and click Browse 3. In the folder selection dialog, point to this path: "D:\VirtIO\vioscsi\w11\amd64" (replace amd64 with ARM64 if you are using Windows on ARM, and "D:" with the drive letter of the ISO) 4. Select all drivers that will appear in the list box and click OK" + + + To continue with OS installation, use a tool to create bootable USB drives, such as Rufus or Ventoy, and install the system. + +If you want to continue customizing this system, use either of the following: Enter the information that will be used to create the first user account on the target system. Additional users can be created later. You can skip entering this information. In that case, default values will be used. diff --git a/MicroWin/MicroWin.csproj b/MicroWin/MicroWin.csproj index 9612a4e..0f51dbd 100755 --- a/MicroWin/MicroWin.csproj +++ b/MicroWin/MicroWin.csproj @@ -18,6 +18,14 @@ 2.1.0.0 + + + + + + + + @@ -30,6 +38,11 @@ + + + + + diff --git a/MicroWin/Resources/Regional/GeoId.xml b/MicroWin/Resources/Regional/GeoId.xml new file mode 100644 index 0000000..a978a5d --- /dev/null +++ b/MicroWin/Resources/Regional/GeoId.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MicroWin/Resources/Regional/ImageLanguage.xml b/MicroWin/Resources/Regional/ImageLanguage.xml new file mode 100644 index 0000000..68ff579 --- /dev/null +++ b/MicroWin/Resources/Regional/ImageLanguage.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MicroWin/Resources/Regional/KeyboardIdentifier.xml b/MicroWin/Resources/Regional/KeyboardIdentifier.xml new file mode 100644 index 0000000..c1b9daf --- /dev/null +++ b/MicroWin/Resources/Regional/KeyboardIdentifier.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MicroWin/Resources/Regional/TimeOffset.xml b/MicroWin/Resources/Regional/TimeOffset.xml new file mode 100644 index 0000000..3b958d5 --- /dev/null +++ b/MicroWin/Resources/Regional/TimeOffset.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MicroWin/Resources/Regional/UserLocale.xml b/MicroWin/Resources/Regional/UserLocale.xml new file mode 100644 index 0000000..6961cd4 --- /dev/null +++ b/MicroWin/Resources/Regional/UserLocale.xml @@ -0,0 +1,689 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MicroWin/functions/Helpers/ProgramResources/ResourceHelper.cs b/MicroWin/functions/Helpers/ProgramResources/ResourceHelper.cs new file mode 100644 index 0000000..c12e191 --- /dev/null +++ b/MicroWin/functions/Helpers/ProgramResources/ResourceHelper.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace MicroWin.functions.Helpers.ProgramResources +{ + public class ResourceHelper + { + + public static Stream? GetProgramResourceStream(string resourceName) { + Assembly currentAssembly = Assembly.GetExecutingAssembly(); + try { + return currentAssembly.GetManifestResourceStream(resourceName); + } catch { + return null; + } + } + + } +} diff --git a/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs b/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs index 9166ea7..96c5875 100644 --- a/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs +++ b/MicroWin/functions/OSCDIMG/OscdimgUtilities.cs @@ -1,4 +1,5 @@ using MicroWin.functions.Helpers.Loggers; +using MicroWin.functions.Helpers.ProgramResources; using MicroWin.functions.Helpers.RegistryHelpers; using System; using System.Diagnostics; @@ -46,8 +47,7 @@ public static void CheckAndInvokeOscdimgBinaries(Action? outputReporter #pragma warning disable CS8600 if (outputReporter is not null) outputReporter.Invoke("Extracting OSCDIMG binaries..."); - Assembly currentAssembly = Assembly.GetExecutingAssembly(); - using Stream resourceStream = currentAssembly.GetManifestResourceStream("MicroWin.tools.oscdimg.exe"); + using Stream resourceStream = ResourceHelper.GetProgramResourceStream("MicroWin.tools.oscdimg.exe"); if (resourceStream is not null) { byte[] oscdimgBytes = new byte[resourceStream.Length]; diff --git a/MicroWin/functions/dism/UnattendGenerator.cs b/MicroWin/functions/dism/UnattendGenerator.cs index 7e81d19..064b11b 100755 --- a/MicroWin/functions/dism/UnattendGenerator.cs +++ b/MicroWin/functions/dism/UnattendGenerator.cs @@ -1,8 +1,11 @@ using MicroWin.Classes; +using MicroWin.Classes.Regional; using MicroWin.functions.Helpers.Loggers; using MicroWin.functions.Helpers.PropertyCheckers; using System; +using System.Globalization; using System.IO; +using System.Security; using System.Text; namespace MicroWin.functions.dism @@ -90,7 +93,23 @@ public static void CreateUnattend(string destinationPath, Version? sourceVersion xml.AppendLine(" "); xml.AppendLine(" "); xml.AppendLine(" "); + xml.AppendLine(" "); + xml.AppendLine(" "); + string? inputLocale = GetInputLocale(AppState.userLocale); + DynaLog.logMessage($"Regional locale settings: locale={AppState.userLocale?.Id ?? "(not set)"}, inputLocale={inputLocale ?? "(not set)"}, GeoID={AppState.userLocale?.GeoLocation ?? "(not set)"}."); + if (!string.IsNullOrEmpty(inputLocale)) + xml.AppendLine($"{EscapeXml(inputLocale)}"); + xml.AppendLine(" "); + if (!string.IsNullOrWhiteSpace(AppState.userLocale?.Id)) + { + xml.AppendLine($" {EscapeXml(AppState.userLocale.Id)}"); + xml.AppendLine($" {EscapeXml(AppState.userLocale.Id)}"); + } + xml.AppendLine(" "); xml.AppendLine(" "); + DynaLog.logMessage($"Regional time zone setting: {AppState.timeOffset?.Id ?? "(not set)"}."); + if (!string.IsNullOrWhiteSpace(AppState.timeOffset?.Id)) + xml.AppendLine($" {EscapeXml(AppState.timeOffset.Id)}"); xml.AppendLine(" "); xml.AppendLine(" "); foreach (UserAccount user in AppState.UserAccounts) @@ -149,6 +168,18 @@ public static void CreateUnattend(string destinationPath, Version? sourceVersion xml.AppendLine(" 4"); xml.AppendLine(" powershell -ExecutionPolicy Bypass -File c:\\windows\\FirstStartup.ps1"); xml.AppendLine(" "); + if (int.TryParse(AppState.userLocale?.GeoLocation, NumberStyles.None, CultureInfo.InvariantCulture, out int geoId)) + { + DynaLog.logMessage($"GeoID {geoId} will be applied during first logon."); + xml.AppendLine(" "); + xml.AppendLine(" 5"); + xml.AppendLine($" powershell.exe -NoProfile -Command \"Set-WinHomeLocation -GeoId {geoId}\""); + xml.AppendLine(" "); + } + else if (!string.IsNullOrWhiteSpace(AppState.userLocale?.GeoLocation)) + { + DynaLog.logMessage($"GeoID value '{AppState.userLocale.GeoLocation}' is invalid and will not be applied."); + } xml.AppendLine(" "); xml.AppendLine(" "); xml.AppendLine(" "); @@ -179,5 +210,37 @@ public static void CreateUnattend(string destinationPath, Version? sourceVersion DynaLog.logMessage($"Unattended file could not be made: {ex.Message}"); } } + + private static string? GetInputLocale(UserLocale? locale) + { + if (locale is null || string.IsNullOrWhiteSpace(locale.KeyboardLayout)) + return null; + + string keyboardLayout = locale.KeyboardLayout; + KeyboardIdentifier? keyboard = KeyboardIdentifier.LoadItems().Find(item => + string.Equals(item.Id, keyboardLayout, StringComparison.OrdinalIgnoreCase)); + + if (keyboard?.GetKeyboardType() == KeyboardType.IME) + return EscapeXml(keyboardLayout); + + string lcid = locale.LCID; + if (string.Equals(lcid, "1000", StringComparison.OrdinalIgnoreCase)) + { + try + { + lcid = CultureInfo.GetCultureInfo(locale.Id).LCID.ToString("x4", CultureInfo.InvariantCulture); + } + catch (CultureNotFoundException) + { + } + } + + return EscapeXml($"{lcid}:{keyboardLayout}"); + } + + private static string EscapeXml(string value) + { + return SecurityElement.Escape(value) ?? string.Empty; + } } } \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..5fcca2a --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.0.1.0 From 50b6d81fcb753deaff97320d5397d9ae75b11c06 Mon Sep 17 00:00:00 2001 From: CodingWonders <101426328+CodingWonders@users.noreply.github.com> Date: Wed, 21 Oct 2026 08:23:26 +0200 Subject: [PATCH 4/5] Update version identifier --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5fcca2a..9c1c5ff 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1.0 +2.1.0.0 From d280ba805470421a883120200ae10009e3255639 Mon Sep 17 00:00:00 2001 From: CodingWonders <101426328+CodingWonders@users.noreply.github.com> Date: Wed, 21 Oct 2026 15:54:46 +0200 Subject: [PATCH 5/5] Add update check and news integration as online services --- MicroWin/MainForm.Designer.cs | 457 +++++++++++++--------- MicroWin/MainForm.cs | 74 +++- MicroWin/MainForm.resx | 10 +- MicroWin/MicroWin.csproj | 1 + MicroWin/Properties/Resources.Designer.cs | 20 + MicroWin/Properties/Resources.resx | 6 + MicroWin/Resources/updates.png | Bin 0 -> 528 bytes MicroWin/Resources/website.png | Bin 0 -> 615 bytes 8 files changed, 385 insertions(+), 183 deletions(-) create mode 100644 MicroWin/Resources/updates.png create mode 100644 MicroWin/Resources/website.png diff --git a/MicroWin/MainForm.Designer.cs b/MicroWin/MainForm.Designer.cs index abe24a9..cf0cc28 100755 --- a/MicroWin/MainForm.Designer.cs +++ b/MicroWin/MainForm.Designer.cs @@ -36,6 +36,25 @@ private void InitializeComponent() Cancel_Button = new Button(); About_Button = new Button(); PageContainerPanel = new Panel(); + WelcomePage = new Panel(); + tlpOnlineServices = new TableLayoutPanel(); + lblNewsDate = new Label(); + lblUpdateStatus = new Label(); + lnkLatestBlogPost = new LinkLabel(); + pictureBox3 = new PictureBox(); + pictureBox4 = new PictureBox(); + lblDisclaimer = new Label(); + WelcomePage_Description = new Label(); + WelcomePage_Header = new Label(); + FinishPage = new Panel(); + lnkViewCreationLogs = new LinkLabel(); + lnkOpenIsoLoc = new LinkLabel(); + panel4 = new Panel(); + lnkUseNtLite = new LinkLabel(); + lnkUseDT = new LinkLabel(); + label18 = new Label(); + label16 = new Label(); + label17 = new Label(); IsoSettingsPage = new Panel(); label19 = new Label(); UEFICA23CB = new CheckBox(); @@ -60,15 +79,6 @@ private void InitializeComponent() comboIme = new ComboBox(); comboRegion = new ComboBox(); label20 = new Label(); - FinishPage = new Panel(); - lnkViewCreationLogs = new LinkLabel(); - lnkOpenIsoLoc = new LinkLabel(); - panel4 = new Panel(); - lnkUseNtLite = new LinkLabel(); - lnkUseDT = new LinkLabel(); - label18 = new Label(); - label16 = new Label(); - label17 = new Label(); IsoCreationPage = new Panel(); pnlProgress = new Panel(); pbOverall = new ProgressBar(); @@ -119,21 +129,21 @@ private void InitializeComponent() label1 = new Label(); SysCheckPage_Description = new Label(); SysCheckPage_Header = new Label(); - WelcomePage = new Panel(); - lblDisclaimer = new Label(); - WelcomePage_Description = new Label(); - WelcomePage_Header = new Label(); winutilConfigDialog = new OpenFileDialog(); isoPickerOFD = new OpenFileDialog(); isoSaverSFD = new SaveFileDialog(); ButtonPanel.SuspendLayout(); TableLayoutPanel1.SuspendLayout(); PageContainerPanel.SuspendLayout(); + WelcomePage.SuspendLayout(); + tlpOnlineServices.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit(); + FinishPage.SuspendLayout(); + panel4.SuspendLayout(); IsoSettingsPage.SuspendLayout(); gbRegionalOptions.SuspendLayout(); tableLayoutPanel4.SuspendLayout(); - FinishPage.SuspendLayout(); - panel4.SuspendLayout(); IsoCreationPage.SuspendLayout(); pnlProgress.SuspendLayout(); UserAccountsPage.SuspendLayout(); @@ -146,7 +156,6 @@ private void InitializeComponent() tableLayoutPanel2.SuspendLayout(); ImageChooserPage.SuspendLayout(); IsoChooserPage.SuspendLayout(); - WelcomePage.SuspendLayout(); SuspendLayout(); // // ButtonPanel @@ -227,13 +236,13 @@ private void InitializeComponent() // // PageContainerPanel // - PageContainerPanel.Controls.Add(IsoSettingsPage); + PageContainerPanel.Controls.Add(WelcomePage); PageContainerPanel.Controls.Add(FinishPage); + PageContainerPanel.Controls.Add(IsoSettingsPage); PageContainerPanel.Controls.Add(IsoCreationPage); PageContainerPanel.Controls.Add(UserAccountsPage); PageContainerPanel.Controls.Add(ImageChooserPage); PageContainerPanel.Controls.Add(IsoChooserPage); - PageContainerPanel.Controls.Add(WelcomePage); PageContainerPanel.Dock = DockStyle.Fill; PageContainerPanel.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 0); PageContainerPanel.Location = new Point(0, 0); @@ -241,6 +250,244 @@ private void InitializeComponent() PageContainerPanel.Size = new Size(1264, 641); PageContainerPanel.TabIndex = 3; // + // WelcomePage + // + WelcomePage.Controls.Add(tlpOnlineServices); + WelcomePage.Controls.Add(lblDisclaimer); + WelcomePage.Controls.Add(WelcomePage_Description); + WelcomePage.Controls.Add(WelcomePage_Header); + WelcomePage.Dock = DockStyle.Fill; + WelcomePage.Location = new Point(0, 0); + WelcomePage.Name = "WelcomePage"; + WelcomePage.Size = new Size(1264, 641); + WelcomePage.TabIndex = 0; + // + // tlpOnlineServices + // + tlpOnlineServices.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + tlpOnlineServices.ColumnCount = 3; + tlpOnlineServices.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 3.649635F)); + tlpOnlineServices.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 96.3503647F)); + tlpOnlineServices.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 260F)); + tlpOnlineServices.Controls.Add(lblNewsDate, 2, 1); + tlpOnlineServices.Controls.Add(lblUpdateStatus, 1, 0); + tlpOnlineServices.Controls.Add(lnkLatestBlogPost, 1, 1); + tlpOnlineServices.Controls.Add(pictureBox3, 0, 0); + tlpOnlineServices.Controls.Add(pictureBox4, 0, 1); + tlpOnlineServices.Font = new Font("Segoe UI", 12F, FontStyle.Bold, GraphicsUnit.Point, 0); + tlpOnlineServices.Location = new Point(30, 547); + tlpOnlineServices.Name = "tlpOnlineServices"; + tlpOnlineServices.RowCount = 2; + tlpOnlineServices.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tlpOnlineServices.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tlpOnlineServices.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F)); + tlpOnlineServices.Size = new Size(1083, 60); + tlpOnlineServices.TabIndex = 2; + // + // lblNewsDate + // + lblNewsDate.AutoSize = true; + lblNewsDate.Dock = DockStyle.Fill; + lblNewsDate.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); + lblNewsDate.Location = new Point(825, 30); + lblNewsDate.Name = "lblNewsDate"; + lblNewsDate.Size = new Size(255, 30); + lblNewsDate.TabIndex = 3; + lblNewsDate.TextAlign = ContentAlignment.MiddleLeft; + // + // lblUpdateStatus + // + lblUpdateStatus.AutoEllipsis = true; + lblUpdateStatus.AutoSize = true; + tlpOnlineServices.SetColumnSpan(lblUpdateStatus, 2); + lblUpdateStatus.Dock = DockStyle.Fill; + lblUpdateStatus.Location = new Point(33, 0); + lblUpdateStatus.Name = "lblUpdateStatus"; + lblUpdateStatus.Size = new Size(1047, 30); + lblUpdateStatus.TabIndex = 0; + lblUpdateStatus.Text = "Checking for updates..."; + lblUpdateStatus.TextAlign = ContentAlignment.MiddleLeft; + // + // lnkLatestBlogPost + // + lnkLatestBlogPost.AutoEllipsis = true; + lnkLatestBlogPost.AutoSize = true; + lnkLatestBlogPost.Dock = DockStyle.Fill; + lnkLatestBlogPost.LinkBehavior = LinkBehavior.NeverUnderline; + lnkLatestBlogPost.LinkColor = Color.DodgerBlue; + lnkLatestBlogPost.Location = new Point(33, 30); + lnkLatestBlogPost.Name = "lnkLatestBlogPost"; + lnkLatestBlogPost.Size = new Size(786, 30); + lnkLatestBlogPost.TabIndex = 1; + lnkLatestBlogPost.TextAlign = ContentAlignment.MiddleLeft; + lnkLatestBlogPost.LinkClicked += lnkLatestBlogPost_LinkClicked; + // + // pictureBox3 + // + pictureBox3.Dock = DockStyle.Fill; + pictureBox3.Image = Properties.Resources.updates; + pictureBox3.Location = new Point(3, 3); + pictureBox3.Name = "pictureBox3"; + pictureBox3.Size = new Size(24, 24); + pictureBox3.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox3.TabIndex = 2; + pictureBox3.TabStop = false; + // + // pictureBox4 + // + pictureBox4.Dock = DockStyle.Fill; + pictureBox4.Image = Properties.Resources.website; + pictureBox4.InitialImage = null; + pictureBox4.Location = new Point(3, 33); + pictureBox4.Name = "pictureBox4"; + pictureBox4.Size = new Size(24, 24); + pictureBox4.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox4.TabIndex = 2; + pictureBox4.TabStop = false; + // + // lblDisclaimer + // + lblDisclaimer.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + lblDisclaimer.AutoEllipsis = true; + lblDisclaimer.Location = new Point(119, 128); + lblDisclaimer.Name = "lblDisclaimer"; + lblDisclaimer.Size = new Size(1026, 368); + lblDisclaimer.TabIndex = 1; + // + // WelcomePage_Description + // + WelcomePage_Description.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + WelcomePage_Description.AutoEllipsis = true; + WelcomePage_Description.Location = new Point(17, 64); + WelcomePage_Description.Name = "WelcomePage_Description"; + WelcomePage_Description.Size = new Size(1233, 172); + WelcomePage_Description.TabIndex = 1; + WelcomePage_Description.Text = "This wizard will help you configure your Windows image. To begin, click Next."; + // + // WelcomePage_Header + // + WelcomePage_Header.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + WelcomePage_Header.AutoEllipsis = true; + WelcomePage_Header.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); + WelcomePage_Header.Location = new Point(14, 12); + WelcomePage_Header.Name = "WelcomePage_Header"; + WelcomePage_Header.Size = new Size(1236, 45); + WelcomePage_Header.TabIndex = 0; + WelcomePage_Header.Text = "Welcome"; + // + // FinishPage + // + FinishPage.Controls.Add(lnkViewCreationLogs); + FinishPage.Controls.Add(lnkOpenIsoLoc); + FinishPage.Controls.Add(panel4); + FinishPage.Controls.Add(label16); + FinishPage.Controls.Add(label17); + FinishPage.Dock = DockStyle.Fill; + FinishPage.Location = new Point(0, 0); + FinishPage.Name = "FinishPage"; + FinishPage.Size = new Size(1264, 641); + FinishPage.TabIndex = 8; + // + // lnkViewCreationLogs + // + lnkViewCreationLogs.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + lnkViewCreationLogs.AutoSize = true; + lnkViewCreationLogs.LinkBehavior = LinkBehavior.NeverUnderline; + lnkViewCreationLogs.LinkColor = Color.DodgerBlue; + lnkViewCreationLogs.Location = new Point(99, 561); + lnkViewCreationLogs.Name = "lnkViewCreationLogs"; + lnkViewCreationLogs.Size = new Size(124, 15); + lnkViewCreationLogs.TabIndex = 12; + lnkViewCreationLogs.TabStop = true; + lnkViewCreationLogs.Text = "View ISO creation logs"; + lnkViewCreationLogs.LinkClicked += lnkViewCreationLogs_LinkClicked; + // + // lnkOpenIsoLoc + // + lnkOpenIsoLoc.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + lnkOpenIsoLoc.AutoSize = true; + lnkOpenIsoLoc.LinkBehavior = LinkBehavior.NeverUnderline; + lnkOpenIsoLoc.LinkColor = Color.DodgerBlue; + lnkOpenIsoLoc.Location = new Point(99, 536); + lnkOpenIsoLoc.Name = "lnkOpenIsoLoc"; + lnkOpenIsoLoc.Size = new Size(103, 15); + lnkOpenIsoLoc.TabIndex = 12; + lnkOpenIsoLoc.TabStop = true; + lnkOpenIsoLoc.Text = "Open ISO location"; + lnkOpenIsoLoc.LinkClicked += lnkOpenIsoLoc_LinkClicked; + // + // panel4 + // + panel4.Anchor = AnchorStyles.None; + panel4.Controls.Add(lnkUseNtLite); + panel4.Controls.Add(lnkUseDT); + panel4.Controls.Add(label18); + panel4.Location = new Point(229, 183); + panel4.Name = "panel4"; + panel4.Size = new Size(806, 276); + panel4.TabIndex = 11; + // + // lnkUseNtLite + // + lnkUseNtLite.AutoSize = true; + lnkUseNtLite.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); + lnkUseNtLite.LinkBehavior = LinkBehavior.NeverUnderline; + lnkUseNtLite.LinkColor = Color.DodgerBlue; + lnkUseNtLite.Location = new Point(101, 193); + lnkUseNtLite.Name = "lnkUseNtLite"; + lnkUseNtLite.Size = new Size(55, 21); + lnkUseNtLite.TabIndex = 11; + lnkUseNtLite.TabStop = true; + lnkUseNtLite.Text = "NTLite"; + lnkUseNtLite.LinkClicked += lnkUseNtLite_LinkClicked; + // + // lnkUseDT + // + lnkUseDT.AutoSize = true; + lnkUseDT.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); + lnkUseDT.LinkBehavior = LinkBehavior.NeverUnderline; + lnkUseDT.LinkColor = Color.DodgerBlue; + lnkUseDT.Location = new Point(101, 160); + lnkUseDT.Name = "lnkUseDT"; + lnkUseDT.Size = new Size(83, 21); + lnkUseDT.TabIndex = 11; + lnkUseDT.TabStop = true; + lnkUseDT.Text = "DISMTools"; + lnkUseDT.LinkClicked += lnkUseDT_LinkClicked; + // + // label18 + // + label18.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label18.AutoEllipsis = true; + label18.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); + label18.Location = new Point(51, 31); + label18.Name = "label18"; + label18.Size = new Size(704, 95); + label18.TabIndex = 10; + label18.Text = resources.GetString("label18.Text"); + label18.TextAlign = ContentAlignment.TopCenter; + // + // label16 + // + label16.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + label16.AutoEllipsis = true; + label16.Location = new Point(17, 64); + label16.Name = "label16"; + label16.Size = new Size(1233, 172); + label16.TabIndex = 10; + label16.Text = "Your ISO file is now ready for operating system installation."; + // + // label17 + // + label17.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label17.AutoEllipsis = true; + label17.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); + label17.Location = new Point(14, 12); + label17.Name = "label17"; + label17.Size = new Size(1236, 45); + label17.TabIndex = 9; + label17.Text = "Customizations complete"; + // // IsoSettingsPage // IsoSettingsPage.Controls.Add(label19); @@ -519,119 +766,6 @@ private void InitializeComponent() label20.TabIndex = 0; label20.Text = "Configure the regional options for the target system. You can change these after the operating system finishes installing."; // - // FinishPage - // - FinishPage.Controls.Add(lnkViewCreationLogs); - FinishPage.Controls.Add(lnkOpenIsoLoc); - FinishPage.Controls.Add(panel4); - FinishPage.Controls.Add(label16); - FinishPage.Controls.Add(label17); - FinishPage.Dock = DockStyle.Fill; - FinishPage.Location = new Point(0, 0); - FinishPage.Name = "FinishPage"; - FinishPage.Size = new Size(1264, 641); - FinishPage.TabIndex = 8; - // - // lnkViewCreationLogs - // - lnkViewCreationLogs.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - lnkViewCreationLogs.AutoSize = true; - lnkViewCreationLogs.LinkBehavior = LinkBehavior.NeverUnderline; - lnkViewCreationLogs.LinkColor = Color.DodgerBlue; - lnkViewCreationLogs.Location = new Point(99, 561); - lnkViewCreationLogs.Name = "lnkViewCreationLogs"; - lnkViewCreationLogs.Size = new Size(124, 15); - lnkViewCreationLogs.TabIndex = 12; - lnkViewCreationLogs.TabStop = true; - lnkViewCreationLogs.Text = "View ISO creation logs"; - lnkViewCreationLogs.LinkClicked += lnkViewCreationLogs_LinkClicked; - // - // lnkOpenIsoLoc - // - lnkOpenIsoLoc.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - lnkOpenIsoLoc.AutoSize = true; - lnkOpenIsoLoc.LinkBehavior = LinkBehavior.NeverUnderline; - lnkOpenIsoLoc.LinkColor = Color.DodgerBlue; - lnkOpenIsoLoc.Location = new Point(99, 536); - lnkOpenIsoLoc.Name = "lnkOpenIsoLoc"; - lnkOpenIsoLoc.Size = new Size(103, 15); - lnkOpenIsoLoc.TabIndex = 12; - lnkOpenIsoLoc.TabStop = true; - lnkOpenIsoLoc.Text = "Open ISO location"; - lnkOpenIsoLoc.LinkClicked += lnkOpenIsoLoc_LinkClicked; - // - // panel4 - // - panel4.Anchor = AnchorStyles.None; - panel4.Controls.Add(lnkUseNtLite); - panel4.Controls.Add(lnkUseDT); - panel4.Controls.Add(label18); - panel4.Location = new Point(229, 183); - panel4.Name = "panel4"; - panel4.Size = new Size(806, 276); - panel4.TabIndex = 11; - // - // lnkUseNtLite - // - lnkUseNtLite.AutoSize = true; - lnkUseNtLite.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); - lnkUseNtLite.LinkBehavior = LinkBehavior.NeverUnderline; - lnkUseNtLite.LinkColor = Color.DodgerBlue; - lnkUseNtLite.Location = new Point(101, 193); - lnkUseNtLite.Name = "lnkUseNtLite"; - lnkUseNtLite.Size = new Size(55, 21); - lnkUseNtLite.TabIndex = 11; - lnkUseNtLite.TabStop = true; - lnkUseNtLite.Text = "NTLite"; - lnkUseNtLite.LinkClicked += lnkUseNtLite_LinkClicked; - // - // lnkUseDT - // - lnkUseDT.AutoSize = true; - lnkUseDT.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); - lnkUseDT.LinkBehavior = LinkBehavior.NeverUnderline; - lnkUseDT.LinkColor = Color.DodgerBlue; - lnkUseDT.Location = new Point(101, 160); - lnkUseDT.Name = "lnkUseDT"; - lnkUseDT.Size = new Size(83, 21); - lnkUseDT.TabIndex = 11; - lnkUseDT.TabStop = true; - lnkUseDT.Text = "DISMTools"; - lnkUseDT.LinkClicked += lnkUseDT_LinkClicked; - // - // label18 - // - label18.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label18.AutoEllipsis = true; - label18.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0); - label18.Location = new Point(51, 31); - label18.Name = "label18"; - label18.Size = new Size(704, 95); - label18.TabIndex = 10; - label18.Text = resources.GetString("label18.Text"); - label18.TextAlign = ContentAlignment.TopCenter; - // - // label16 - // - label16.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - label16.AutoEllipsis = true; - label16.Location = new Point(17, 64); - label16.Name = "label16"; - label16.Size = new Size(1233, 172); - label16.TabIndex = 10; - label16.Text = "Your ISO file is now ready for operating system installation."; - // - // label17 - // - label17.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label17.AutoEllipsis = true; - label17.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); - label17.Location = new Point(14, 12); - label17.Name = "label17"; - label17.Size = new Size(1236, 45); - label17.TabIndex = 9; - label17.Text = "Customizations complete"; - // // IsoCreationPage // IsoCreationPage.Controls.Add(pnlProgress); @@ -1171,47 +1305,6 @@ private void InitializeComponent() SysCheckPage_Header.TabIndex = 0; SysCheckPage_Header.Text = "Choose a disc image"; // - // WelcomePage - // - WelcomePage.Controls.Add(lblDisclaimer); - WelcomePage.Controls.Add(WelcomePage_Description); - WelcomePage.Controls.Add(WelcomePage_Header); - WelcomePage.Dock = DockStyle.Fill; - WelcomePage.Location = new Point(0, 0); - WelcomePage.Name = "WelcomePage"; - WelcomePage.Size = new Size(1264, 641); - WelcomePage.TabIndex = 0; - // - // lblDisclaimer - // - lblDisclaimer.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - lblDisclaimer.AutoEllipsis = true; - lblDisclaimer.Location = new Point(119, 128); - lblDisclaimer.Name = "lblDisclaimer"; - lblDisclaimer.Size = new Size(1026, 433); - lblDisclaimer.TabIndex = 1; - // - // WelcomePage_Description - // - WelcomePage_Description.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - WelcomePage_Description.AutoEllipsis = true; - WelcomePage_Description.Location = new Point(17, 64); - WelcomePage_Description.Name = "WelcomePage_Description"; - WelcomePage_Description.Size = new Size(1233, 172); - WelcomePage_Description.TabIndex = 1; - WelcomePage_Description.Text = "This wizard will help you configure your Windows image. To begin, click Next."; - // - // WelcomePage_Header - // - WelcomePage_Header.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - WelcomePage_Header.AutoEllipsis = true; - WelcomePage_Header.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); - WelcomePage_Header.Location = new Point(14, 12); - WelcomePage_Header.Name = "WelcomePage_Header"; - WelcomePage_Header.Size = new Size(1236, 45); - WelcomePage_Header.TabIndex = 0; - WelcomePage_Header.Text = "Welcome"; - // // winutilConfigDialog // winutilConfigDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"; @@ -1245,16 +1338,21 @@ private void InitializeComponent() ButtonPanel.ResumeLayout(false); TableLayoutPanel1.ResumeLayout(false); PageContainerPanel.ResumeLayout(false); + WelcomePage.ResumeLayout(false); + tlpOnlineServices.ResumeLayout(false); + tlpOnlineServices.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit(); + FinishPage.ResumeLayout(false); + FinishPage.PerformLayout(); + panel4.ResumeLayout(false); + panel4.PerformLayout(); IsoSettingsPage.ResumeLayout(false); IsoSettingsPage.PerformLayout(); gbRegionalOptions.ResumeLayout(false); gbRegionalOptions.PerformLayout(); tableLayoutPanel4.ResumeLayout(false); tableLayoutPanel4.PerformLayout(); - FinishPage.ResumeLayout(false); - FinishPage.PerformLayout(); - panel4.ResumeLayout(false); - panel4.PerformLayout(); IsoCreationPage.ResumeLayout(false); IsoCreationPage.PerformLayout(); pnlProgress.ResumeLayout(false); @@ -1275,7 +1373,6 @@ private void InitializeComponent() ImageChooserPage.PerformLayout(); IsoChooserPage.ResumeLayout(false); IsoChooserPage.PerformLayout(); - WelcomePage.ResumeLayout(false); ResumeLayout(false); } @@ -1379,5 +1476,11 @@ private void InitializeComponent() private ComboBox comboTimeFormat; private ComboBox comboIme; private ComboBox comboRegion; + private TableLayoutPanel tlpOnlineServices; + private Label lblUpdateStatus; + private LinkLabel lnkLatestBlogPost; + private PictureBox pictureBox3; + private PictureBox pictureBox4; + private Label lblNewsDate; } } diff --git a/MicroWin/MainForm.cs b/MicroWin/MainForm.cs index b6cd3d9..b4ee66c 100755 --- a/MicroWin/MainForm.cs +++ b/MicroWin/MainForm.cs @@ -30,6 +30,10 @@ using System.Threading.Tasks; using System.Windows.Forms; +using System.ServiceModel.Syndication; +using System.Net; +using System.Xml; + namespace MicroWin { [SupportedOSPlatform("Windows")] @@ -284,7 +288,7 @@ private bool VerifyOptionsInPage(WizardPage.Page wizardPage) return true; } - private void MainForm_Load(object sender, EventArgs e) + private async void MainForm_Load(object sender, EventArgs e) { string welcomeMessage = $"Welcome to MicroWin .NET.\n\n" + $"This wizard will guide you through the creation of your ISO file, with a debloated Windows experience. You will need an official " + @@ -349,8 +353,69 @@ private void MainForm_Load(object sender, EventArgs e) AppState.userLocale = finalLocale.Clone(); AppState.timeOffset = finalOffset.Clone(); + + await CheckFeedsAsync(); + if (feedContents is not null && feedContents.Items.Any()) + { + lnkLatestBlogPost.Text = feedContents.Items.ElementAt(0).Title.Text; + lblNewsDate.Text = feedContents.Items.ElementAt(0).PublishDate.ToString("D"); + } + + bool updatesAvailable = await AreUpdatesAvailableAsync(); + if (updatesAvailable) { + lblUpdateStatus.Text = $"Updates are available. The latest version is {targetVer}."; + } else { + lblUpdateStatus.Text = "You are up to date."; + } + } + + // Online Services + SyndicationFeed? feedContents = new(); + private static readonly HttpClient client = new(); + + private async Task CheckFeedsAsync() + { + try + { + const string rssUrl = "https://codingwonders.github.io/feed.xml"; + string rssContent = await client.GetStringAsync(rssUrl); + + if (!string.IsNullOrWhiteSpace(rssContent)) + { + using XmlReader reader = XmlReader.Create(new StringReader(rssContent)); + feedContents = SyndicationFeed.Load(reader); + } + } + catch (Exception) + { + feedContents = null; + } } + private string targetVer = ""; + + private async Task AreUpdatesAvailableAsync() { + try + { + const string updateUrl = "https://raw.githubusercontent.com/CodingWonders/MicroWin/refs/heads/main/VERSION"; + + string verIdentifierContent = await client.GetStringAsync(updateUrl); + + if (Version.TryParse(verIdentifierContent, out Version? latestVersion)) + { + targetVer = verIdentifierContent; + return !VersionComparer.IsNewerThanVersion(new Version(Application.ProductVersion), latestVersion); + } + else + { + return false; + } + } + catch (Exception) + { + return false; + } + } private void Next_Button_Click(object sender, EventArgs e) { @@ -1271,5 +1336,12 @@ private void comboOffset_SelectedIndexChanged(object sender, EventArgs e) finalOffset = timeOffsets[comboOffset.SelectedIndex].Clone(); AppState.timeOffset = finalOffset.Clone(); } + + private void lnkLatestBlogPost_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + if (feedContents is not null && feedContents.Items.Any()) { + Process.Start(new ProcessStartInfo() { UseShellExecute = true, FileName = feedContents.Items.ElementAt(0).Links[0].Uri.ToString() }); + } + } } } diff --git a/MicroWin/MainForm.resx b/MicroWin/MainForm.resx index f6568f5..b0a6ead 100644 --- a/MicroWin/MainForm.resx +++ b/MicroWin/MainForm.resx @@ -117,17 +117,17 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + To continue with OS installation, use a tool to create bootable USB drives, such as Rufus or Ventoy, and install the system. + +If you want to continue customizing this system, use either of the following: + To proceed with installation of the MicroWin image in QEMU/Proxmox VE: 1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives 2. Click "Load Driver" and click Browse 3. In the folder selection dialog, point to this path: "D:\VirtIO\vioscsi\w11\amd64" (replace amd64 with ARM64 if you are using Windows on ARM, and "D:" with the drive letter of the ISO) 4. Select all drivers that will appear in the list box and click OK" - - - To continue with OS installation, use a tool to create bootable USB drives, such as Rufus or Ventoy, and install the system. - -If you want to continue customizing this system, use either of the following: Enter the information that will be used to create the first user account on the target system. Additional users can be created later. You can skip entering this information. In that case, default values will be used. diff --git a/MicroWin/MicroWin.csproj b/MicroWin/MicroWin.csproj index 0f51dbd..299a741 100755 --- a/MicroWin/MicroWin.csproj +++ b/MicroWin/MicroWin.csproj @@ -34,6 +34,7 @@ + diff --git a/MicroWin/Properties/Resources.Designer.cs b/MicroWin/Properties/Resources.Designer.cs index 697abe1..0333eeb 100755 --- a/MicroWin/Properties/Resources.Designer.cs +++ b/MicroWin/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ internal Resources() { } } + /// + /// Busca un recurso adaptado de tipo System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap updates { + get { + object obj = ResourceManager.GetObject("updates", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Busca un recurso adaptado de tipo System.Drawing.Bitmap. /// @@ -80,6 +90,16 @@ public static System.Drawing.Bitmap user_creation_settings { } } + /// + /// Busca un recurso adaptado de tipo System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap website { + get { + object obj = ResourceManager.GetObject("website", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Busca un recurso adaptado de tipo System.IO.UnmanagedMemoryStream similar a System.IO.MemoryStream. /// diff --git a/MicroWin/Properties/Resources.resx b/MicroWin/Properties/Resources.resx index 7b24f08..65cd0b8 100755 --- a/MicroWin/Properties/Resources.resx +++ b/MicroWin/Properties/Resources.resx @@ -118,12 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\updates.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\user_creation_lusrmgr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\user_creation_settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\website.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\yapper_password.wav;System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/MicroWin/Resources/updates.png b/MicroWin/Resources/updates.png new file mode 100644 index 0000000000000000000000000000000000000000..b97d15168c2264117e0eb25ef47e1969ad997fcd GIT binary patch literal 528 zcmV+r0`L8aP)z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA00(qQO+^Rl3Kb15EBPNzcK`qZ zW=TXrR7l6|mD?(WVHAd+PZ5%G0Y=Cr2q{DZy9G4rL)& zj2idn$hZ)h?5U|)!?5D3Of-w2J*I54Uf)s&=u&s$bmeru0n7piz^J;Q7Ww47?7Nin zkVNet)f4q8?xlJ_DU?qE`Uv=);B$b7ZvnoQ=n_~0&VWkXFS8P)lxn~nup4JSbYCJV zMx)xBH3?IZ;%c)9QuL#$7IN4Ps2A#D7VuE~_NQ4$)V^?DRR{B|=-V(_RolM7bgFC7 zvpaP-@46lUiohgr50qkEw*dXI#=C*NSl8Eo?aQ>f9^17R(H@0v?Egt_SY803&!8Ya S(?yg30000z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA00(qQO+^Rl3Kb14C`&s`4gdfF zy-7qtR7l6&l}l<=Q4of|n{*p+1B#lFkC7-SnTrcB9SIHvmmq;;2^zs9E+7#MLQc?Q-8hgId!TI{Oc&1lu?9Yep ze#osj(xbQ>zc}3S&tbNV+e$e)z!%_Y;_d=pfz3XrIt!cxo+a*H#M-Rx;85MDa9wr1 zp=Rr9x590x2c?{^)fwPjCB|vsW5d1p6gC;hz}dP4b)D^iZZCjd6PFWw046KOpKJaw z<5biwV>0hL7kLM`sV*dL0+_0B8B@SSMSlZ$`PZ&#PS950_Gz?BHTD-qYP2w#38&?d zuZ%D%R$|KD8Z?g#xtuFE8Q>RQdXUI=b2Yv002ovPDHLkV1mML B1DF5+ literal 0 HcmV?d00001