diff --git a/MicroWin/AppState.cs b/MicroWin/AppState.cs index ffeb810..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,7 +25,9 @@ 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.0"; + public static string Version => "v2.1"; } } \ No newline at end of file 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..cf0cc28 100755 --- a/MicroWin/MainForm.Designer.cs +++ b/MicroWin/MainForm.Designer.cs @@ -36,6 +36,16 @@ 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(); @@ -45,15 +55,6 @@ private void InitializeComponent() label18 = new Label(); label16 = new Label(); label17 = new Label(); - IsoCreationPage = new Panel(); - pnlProgress = new Panel(); - pbOverall = new ProgressBar(); - pbCurrent = new ProgressBar(); - lblOverallStatus = new Label(); - lblCurrentStatus = new Label(); - logTB = new TextBox(); - label14 = new Label(); - label15 = new Label(); IsoSettingsPage = new Panel(); label19 = new Label(); UEFICA23CB = new CheckBox(); @@ -67,6 +68,26 @@ private void InitializeComponent() 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(); + IsoCreationPage = new Panel(); + pnlProgress = new Panel(); + pbOverall = new ProgressBar(); + pbCurrent = new ProgressBar(); + lblOverallStatus = new Label(); + lblCurrentStatus = new Label(); + logTB = new TextBox(); + label14 = new Label(); + label15 = new Label(); UserAccountsPage = new Panel(); panel1 = new Panel(); tableLayoutPanel3 = new TableLayoutPanel(); @@ -108,21 +129,23 @@ 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(); IsoCreationPage.SuspendLayout(); pnlProgress.SuspendLayout(); - IsoSettingsPage.SuspendLayout(); UserAccountsPage.SuspendLayout(); panel1.SuspendLayout(); tableLayoutPanel3.SuspendLayout(); @@ -133,7 +156,6 @@ private void InitializeComponent() tableLayoutPanel2.SuspendLayout(); ImageChooserPage.SuspendLayout(); IsoChooserPage.SuspendLayout(); - WelcomePage.SuspendLayout(); SuspendLayout(); // // ButtonPanel @@ -214,13 +236,13 @@ private void InitializeComponent() // // PageContainerPanel // + PageContainerPanel.Controls.Add(WelcomePage); PageContainerPanel.Controls.Add(FinishPage); - PageContainerPanel.Controls.Add(IsoCreationPage); 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); @@ -228,6 +250,131 @@ 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); @@ -341,99 +488,6 @@ private void InitializeComponent() label17.TabIndex = 9; label17.Text = "Customizations complete"; // - // IsoCreationPage - // - IsoCreationPage.Controls.Add(pnlProgress); - IsoCreationPage.Controls.Add(logTB); - IsoCreationPage.Controls.Add(label14); - IsoCreationPage.Controls.Add(label15); - IsoCreationPage.Dock = DockStyle.Fill; - IsoCreationPage.Location = new Point(0, 0); - IsoCreationPage.Name = "IsoCreationPage"; - IsoCreationPage.Size = new Size(1264, 641); - IsoCreationPage.TabIndex = 7; - // - // pnlProgress - // - pnlProgress.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - pnlProgress.Controls.Add(pbOverall); - pnlProgress.Controls.Add(pbCurrent); - pnlProgress.Controls.Add(lblOverallStatus); - pnlProgress.Controls.Add(lblCurrentStatus); - pnlProgress.Location = new Point(19, 525); - pnlProgress.Name = "pnlProgress"; - pnlProgress.Size = new Size(1227, 110); - pnlProgress.TabIndex = 10; - // - // pbOverall - // - pbOverall.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - pbOverall.Location = new Point(14, 77); - pbOverall.Name = "pbOverall"; - pbOverall.Size = new Size(1197, 23); - pbOverall.TabIndex = 1; - // - // pbCurrent - // - pbCurrent.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - pbCurrent.Location = new Point(14, 30); - pbCurrent.Name = "pbCurrent"; - pbCurrent.Size = new Size(1197, 23); - pbCurrent.TabIndex = 1; - // - // lblOverallStatus - // - lblOverallStatus.AutoSize = true; - lblOverallStatus.Location = new Point(11, 58); - lblOverallStatus.Name = "lblOverallStatus"; - lblOverallStatus.Size = new Size(95, 15); - lblOverallStatus.TabIndex = 0; - lblOverallStatus.Text = "Overall Progress:"; - // - // lblCurrentStatus - // - lblCurrentStatus.AutoSize = true; - lblCurrentStatus.Location = new Point(11, 11); - lblCurrentStatus.Name = "lblCurrentStatus"; - lblCurrentStatus.Size = new Size(98, 15); - lblCurrentStatus.TabIndex = 0; - lblCurrentStatus.Text = "Current Progress:"; - // - // logTB - // - logTB.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - logTB.BorderStyle = BorderStyle.None; - logTB.Font = new Font("Courier New", 11.25F, FontStyle.Regular, GraphicsUnit.Point, 0); - logTB.Location = new Point(99, 128); - logTB.MaxLength = int.MaxValue; - logTB.Multiline = true; - logTB.Name = "logTB"; - logTB.ReadOnly = true; - logTB.ScrollBars = ScrollBars.Vertical; - logTB.Size = new Size(1046, 368); - logTB.TabIndex = 9; - // - // label14 - // - label14.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - label14.AutoEllipsis = true; - label14.Location = new Point(17, 64); - label14.Name = "label14"; - label14.Size = new Size(1233, 172); - label14.TabIndex = 8; - label14.Text = "This process will take several minutes; please be patient."; - // - // label15 - // - label15.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label15.AutoEllipsis = true; - label15.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); - label15.Location = new Point(14, 12); - label15.Name = "label15"; - label15.Size = new Size(1236, 45); - label15.TabIndex = 7; - label15.Text = "Customizations in progress"; - // // IsoSettingsPage // IsoSettingsPage.Controls.Add(label19); @@ -448,6 +502,7 @@ private void InitializeComponent() 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"; @@ -458,9 +513,9 @@ private void InitializeComponent() // label19.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; label19.AutoEllipsis = true; - label19.Location = new Point(101, 340); + label19.Location = new Point(101, 504); label19.Name = "label19"; - label19.Size = new Size(1062, 243); + label19.Size = new Size(1084, 89); label19.TabIndex = 14; label19.Text = resources.GetString("label19.Text"); label19.Visible = false; @@ -470,7 +525,7 @@ private void InitializeComponent() UEFICA23CB.AutoSize = true; UEFICA23CB.Checked = true; UEFICA23CB.CheckState = CheckState.Checked; - UEFICA23CB.Location = new Point(83, 235); + UEFICA23CB.Location = new Point(83, 399); UEFICA23CB.Name = "UEFICA23CB"; UEFICA23CB.Size = new Size(380, 19); UEFICA23CB.TabIndex = 10; @@ -482,7 +537,7 @@ private void InitializeComponent() // 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.Location = new Point(83, 370); DriverExportCombo.Name = "DriverExportCombo"; DriverExportCombo.Size = new Size(412, 23); DriverExportCombo.TabIndex = 9; @@ -491,7 +546,7 @@ private void InitializeComponent() // label13 // label13.AutoSize = true; - label13.Location = new Point(80, 185); + label13.Location = new Point(80, 349); label13.Name = "label13"; label13.Size = new Size(111, 15); label13.TabIndex = 8; @@ -500,7 +555,7 @@ private void InitializeComponent() // UnattendCopyCB // UnattendCopyCB.AutoSize = true; - UnattendCopyCB.Location = new Point(83, 158); + UnattendCopyCB.Location = new Point(83, 322); UnattendCopyCB.Name = "UnattendCopyCB"; UnattendCopyCB.Size = new Size(412, 19); UnattendCopyCB.TabIndex = 7; @@ -513,7 +568,7 @@ private void InitializeComponent() ReportToolCB.AutoSize = true; ReportToolCB.Checked = true; ReportToolCB.CheckState = CheckState.Checked; - ReportToolCB.Location = new Point(83, 133); + ReportToolCB.Location = new Point(83, 297); ReportToolCB.Name = "ReportToolCB"; ReportToolCB.Size = new Size(218, 19); ReportToolCB.TabIndex = 7; @@ -545,7 +600,7 @@ private void InitializeComponent() // winutilConfigLabel // winutilConfigLabel.AutoSize = true; - winutilConfigLabel.Location = new Point(80, 265); + winutilConfigLabel.Location = new Point(80, 429); winutilConfigLabel.Name = "winutilConfigLabel"; winutilConfigLabel.Size = new Size(127, 15); winutilConfigLabel.TabIndex = 11; @@ -553,7 +608,7 @@ private void InitializeComponent() // // winutilConfigTextBox // - winutilConfigTextBox.Location = new Point(83, 286); + winutilConfigTextBox.Location = new Point(83, 450); winutilConfigTextBox.Name = "winutilConfigTextBox"; winutilConfigTextBox.Size = new Size(293, 23); winutilConfigTextBox.TabIndex = 12; @@ -562,7 +617,7 @@ private void InitializeComponent() // winutilConfigBrowseBtn // winutilConfigBrowseBtn.FlatStyle = FlatStyle.System; - winutilConfigBrowseBtn.Location = new Point(382, 285); + winutilConfigBrowseBtn.Location = new Point(382, 449); winutilConfigBrowseBtn.Name = "winutilConfigBrowseBtn"; winutilConfigBrowseBtn.Size = new Size(80, 23); winutilConfigBrowseBtn.TabIndex = 13; @@ -573,7 +628,7 @@ private void InitializeComponent() // CopyVirtIODrivers // CopyVirtIODrivers.AutoSize = true; - CopyVirtIODrivers.Location = new Point(83, 318); + CopyVirtIODrivers.Location = new Point(83, 482); CopyVirtIODrivers.Name = "CopyVirtIODrivers"; CopyVirtIODrivers.Size = new Size(125, 19); CopyVirtIODrivers.TabIndex = 7; @@ -581,6 +636,229 @@ private void InitializeComponent() 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."; + // + // IsoCreationPage + // + IsoCreationPage.Controls.Add(pnlProgress); + IsoCreationPage.Controls.Add(logTB); + IsoCreationPage.Controls.Add(label14); + IsoCreationPage.Controls.Add(label15); + IsoCreationPage.Dock = DockStyle.Fill; + IsoCreationPage.Location = new Point(0, 0); + IsoCreationPage.Name = "IsoCreationPage"; + IsoCreationPage.Size = new Size(1264, 641); + IsoCreationPage.TabIndex = 7; + // + // pnlProgress + // + pnlProgress.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + pnlProgress.Controls.Add(pbOverall); + pnlProgress.Controls.Add(pbCurrent); + pnlProgress.Controls.Add(lblOverallStatus); + pnlProgress.Controls.Add(lblCurrentStatus); + pnlProgress.Location = new Point(19, 525); + pnlProgress.Name = "pnlProgress"; + pnlProgress.Size = new Size(1227, 110); + pnlProgress.TabIndex = 10; + // + // pbOverall + // + pbOverall.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + pbOverall.Location = new Point(14, 77); + pbOverall.Name = "pbOverall"; + pbOverall.Size = new Size(1197, 23); + pbOverall.TabIndex = 1; + // + // pbCurrent + // + pbCurrent.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + pbCurrent.Location = new Point(14, 30); + pbCurrent.Name = "pbCurrent"; + pbCurrent.Size = new Size(1197, 23); + pbCurrent.TabIndex = 1; + // + // lblOverallStatus + // + lblOverallStatus.AutoSize = true; + lblOverallStatus.Location = new Point(11, 58); + lblOverallStatus.Name = "lblOverallStatus"; + lblOverallStatus.Size = new Size(95, 15); + lblOverallStatus.TabIndex = 0; + lblOverallStatus.Text = "Overall Progress:"; + // + // lblCurrentStatus + // + lblCurrentStatus.AutoSize = true; + lblCurrentStatus.Location = new Point(11, 11); + lblCurrentStatus.Name = "lblCurrentStatus"; + lblCurrentStatus.Size = new Size(98, 15); + lblCurrentStatus.TabIndex = 0; + lblCurrentStatus.Text = "Current Progress:"; + // + // logTB + // + logTB.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + logTB.BorderStyle = BorderStyle.None; + logTB.Font = new Font("Courier New", 11.25F, FontStyle.Regular, GraphicsUnit.Point, 0); + logTB.Location = new Point(99, 128); + logTB.MaxLength = int.MaxValue; + logTB.Multiline = true; + logTB.Name = "logTB"; + logTB.ReadOnly = true; + logTB.ScrollBars = ScrollBars.Vertical; + logTB.Size = new Size(1046, 368); + logTB.TabIndex = 9; + // + // label14 + // + label14.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + label14.AutoEllipsis = true; + label14.Location = new Point(17, 64); + label14.Name = "label14"; + label14.Size = new Size(1233, 172); + label14.TabIndex = 8; + label14.Text = "This process will take several minutes; please be patient."; + // + // label15 + // + label15.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label15.AutoEllipsis = true; + label15.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0); + label15.Location = new Point(14, 12); + label15.Name = "label15"; + label15.Size = new Size(1236, 45); + label15.TabIndex = 7; + label15.Text = "Customizations in progress"; + // // UserAccountsPage // UserAccountsPage.Controls.Add(panel1); @@ -1027,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 (*.*)|*.*"; @@ -1101,16 +1338,25 @@ 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(); IsoCreationPage.ResumeLayout(false); IsoCreationPage.PerformLayout(); pnlProgress.ResumeLayout(false); pnlProgress.PerformLayout(); - IsoSettingsPage.ResumeLayout(false); - IsoSettingsPage.PerformLayout(); UserAccountsPage.ResumeLayout(false); UserAccountsPage.PerformLayout(); panel1.ResumeLayout(false); @@ -1127,7 +1373,6 @@ private void InitializeComponent() ImageChooserPage.PerformLayout(); IsoChooserPage.ResumeLayout(false); IsoChooserPage.PerformLayout(); - WelcomePage.ResumeLayout(false); ResumeLayout(false); } @@ -1220,5 +1465,22 @@ 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; + 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 ffc6c04..b4ee66c 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; @@ -28,13 +30,17 @@ using System.Threading.Tasks; using System.Windows.Forms; +using System.ServiceModel.Syndication; +using System.Net; +using System.Xml; + namespace MicroWin { [SupportedOSPlatform("Windows")] 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 = [ @@ -50,6 +56,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 +106,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 +191,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"); @@ -254,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 " + @@ -292,8 +326,96 @@ 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(); + + 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) { @@ -370,7 +492,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 +900,9 @@ await Task.Run(() => } }); } - } catch { + } + catch + { WriteLogMessage("Could not download VirtIO drivers..."); } } @@ -851,16 +976,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 +1105,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 +1295,53 @@ 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(); + } + + 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/MicroWin.csproj b/MicroWin/MicroWin.csproj index a5f5e3c..299a741 100755 --- a/MicroWin/MicroWin.csproj +++ b/MicroWin/MicroWin.csproj @@ -14,10 +14,18 @@ false logo.ico - 2.0.1.0 - 2.0.1.0 + 2.1.0.0 + 2.1.0.0 + + + + + + + + @@ -26,10 +34,16 @@ + + + + + + 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")] 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/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/Resources/updates.png b/MicroWin/Resources/updates.png new file mode 100644 index 0000000..b97d151 Binary files /dev/null and b/MicroWin/Resources/updates.png differ diff --git a/MicroWin/Resources/website.png b/MicroWin/Resources/website.png new file mode 100644 index 0000000..7b471db Binary files /dev/null and b/MicroWin/Resources/website.png differ 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 432a4e7..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]; @@ -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() 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 index 5fcca2a..9c1c5ff 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1.0 +2.1.0.0