diff --git a/ConsoleApp/ConsoleApp.csproj b/ConsoleApp/ConsoleApp.csproj
index da2b86d..c8aea25 100644
--- a/ConsoleApp/ConsoleApp.csproj
+++ b/ConsoleApp/ConsoleApp.csproj
@@ -12,7 +12,7 @@
none
latest-recommended
ConsoleApp.Program
- 0.0.7.0
+ 0.0.8.0
true
app.manifest
diff --git a/ConsoleApp/src/ArgumentParser.cs b/ConsoleApp/src/ArgumentParser.cs
index 7deb9bb..4ca2def 100644
--- a/ConsoleApp/src/ArgumentParser.cs
+++ b/ConsoleApp/src/ArgumentParser.cs
@@ -59,7 +59,7 @@ internal static void ParseArgs(ref Parameters parameters, string[] args)
parameters.ImageFilePath = args[Array.IndexOf(args, arg) + 1].ToLowerInvariant();
continue;
case "/additionaldriversdrive":
- parameters.AdditionalDriversDrive = args[Array.IndexOf(args, arg) + 1].ToLowerInvariant();
+ parameters.AdditionalDrive = args[Array.IndexOf(args, arg) + 1].ToLowerInvariant();
continue;
case "/firmwaretype":
parameters.FirmwareType = args[Array.IndexOf(args, arg) + 1].ToUpperInvariant();
@@ -80,7 +80,7 @@ internal static void ParseArgs(ref Parameters parameters, string[] args)
Console.WriteLine($" Source Drive: {parameters.SourceDrive}");
Console.WriteLine($" Image Index: {parameters.ImageIndex}");
Console.WriteLine($" Image File Path: {parameters.ImageFilePath}");
- Console.WriteLine($" Additional Drivers Drive: {parameters.AdditionalDriversDrive}");
+ Console.WriteLine($" Additional Drivers Drive: {parameters.AdditionalDrive}");
Console.WriteLine($" Firmware Type: {parameters.FirmwareType}");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
diff --git a/ConsoleApp/src/Program.cs b/ConsoleApp/src/Program.cs
index 30d1231..aba4735 100644
--- a/ConsoleApp/src/Program.cs
+++ b/ConsoleApp/src/Program.cs
@@ -30,36 +30,45 @@ internal static int Main(string[] args)
Console.WriteLine($"Created by {ProgramInfo.GetAuthor()}");
#endif
}
- catch (Exception)
+ catch (Exception ex)
{
- throw;
+ Console.WriteLine($"An error has occurred: {ex.Message}");
}
try
{
ArgumentParser.ParseArgs(ref parameters, args);
}
- catch (Exception)
+ catch (Exception ex)
{
- throw;
+ Console.WriteLine($"An error has occurred: {ex.Message}");
}
try
{
InstallerManager.Configure(ref parameters);
}
- catch (Exception)
+ catch (Exception ex)
{
- throw;
+ Console.WriteLine($"An error has occurred: {ex.Message}");
+ }
+
+ try
+ {
+ InstallerManager.Prepare(ref parameters);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"An error has occurred: {ex.Message}");
}
try
{
InstallerManager.InstallWindows(ref parameters);
}
- catch (Exception)
+ catch (Exception ex)
{
- throw;
+ Console.WriteLine($"An error has occurred: {ex.Message}");
}
return 0;
diff --git a/GUIApp/GUIApp.csproj b/GUIApp/GUIApp.csproj
new file mode 100644
index 0000000..c2fcb04
--- /dev/null
+++ b/GUIApp/GUIApp.csproj
@@ -0,0 +1,54 @@
+
+
+
+ WinExe
+ net10.0-windows
+ enable
+ true
+ wit.Program
+ latest
+ x64
+ none
+ true
+ en-US
+ latest-recommended
+ wit
+ wit
+ x64
+ app.manifest
+ SystemAware
+
+
+
+ 0
+ True
+ none
+ True
+ 1.0.0.0
+ $(Version)
+ $(Version)
+
+
+
+ 9999
+ True
+ full
+ testing
+ True
+ 0.0.3.0
+ testing
+ $(Version)
+ $(Version)
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GUIApp/app.manifest b/GUIApp/app.manifest
new file mode 100644
index 0000000..180aa93
--- /dev/null
+++ b/GUIApp/app.manifest
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GUIApp/src/AboutWindow.Designer.cs b/GUIApp/src/AboutWindow.Designer.cs
new file mode 100644
index 0000000..863d6b2
--- /dev/null
+++ b/GUIApp/src/AboutWindow.Designer.cs
@@ -0,0 +1,187 @@
+namespace wit
+{
+ partial class AboutWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+ logoPictureBox = new System.Windows.Forms.PictureBox();
+ labelProductName = new System.Windows.Forms.Label();
+ labelVersion = new System.Windows.Forms.Label();
+ labelCopyright = new System.Windows.Forms.Label();
+ labelCompanyName = new System.Windows.Forms.Label();
+ textBoxDescription = new System.Windows.Forms.TextBox();
+ okButton = new System.Windows.Forms.Button();
+ tableLayoutPanel.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)logoPictureBox).BeginInit();
+ SuspendLayout();
+ //
+ // tableLayoutPanel
+ //
+ tableLayoutPanel.ColumnCount = 2;
+ tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
+ tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F));
+ tableLayoutPanel.Controls.Add(logoPictureBox, 0, 0);
+ tableLayoutPanel.Controls.Add(labelProductName, 1, 0);
+ tableLayoutPanel.Controls.Add(labelVersion, 1, 1);
+ tableLayoutPanel.Controls.Add(labelCopyright, 1, 2);
+ tableLayoutPanel.Controls.Add(labelCompanyName, 1, 3);
+ tableLayoutPanel.Controls.Add(textBoxDescription, 1, 4);
+ tableLayoutPanel.Controls.Add(okButton, 1, 5);
+ tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ tableLayoutPanel.Location = new System.Drawing.Point(10, 10);
+ tableLayoutPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ tableLayoutPanel.Name = "tableLayoutPanel";
+ tableLayoutPanel.RowCount = 6;
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
+ tableLayoutPanel.Size = new System.Drawing.Size(487, 307);
+ tableLayoutPanel.TabIndex = 0;
+ //
+ // logoPictureBox
+ //
+ logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ logoPictureBox.Location = new System.Drawing.Point(4, 3);
+ logoPictureBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ logoPictureBox.Name = "logoPictureBox";
+ tableLayoutPanel.SetRowSpan(logoPictureBox, 6);
+ logoPictureBox.Size = new System.Drawing.Size(152, 301);
+ logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ logoPictureBox.TabIndex = 12;
+ logoPictureBox.TabStop = false;
+ //
+ // labelProductName
+ //
+ labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
+ labelProductName.Location = new System.Drawing.Point(167, 0);
+ labelProductName.Margin = new System.Windows.Forms.Padding(7, 0, 4, 0);
+ labelProductName.MaximumSize = new System.Drawing.Size(0, 20);
+ labelProductName.Name = "labelProductName";
+ labelProductName.Size = new System.Drawing.Size(316, 20);
+ labelProductName.TabIndex = 19;
+ labelProductName.Text = "Product Name";
+ labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // labelVersion
+ //
+ labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
+ labelVersion.Location = new System.Drawing.Point(167, 30);
+ labelVersion.Margin = new System.Windows.Forms.Padding(7, 0, 4, 0);
+ labelVersion.MaximumSize = new System.Drawing.Size(0, 20);
+ labelVersion.Name = "labelVersion";
+ labelVersion.Size = new System.Drawing.Size(316, 20);
+ labelVersion.TabIndex = 0;
+ labelVersion.Text = "Version";
+ labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // labelCopyright
+ //
+ labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
+ labelCopyright.Location = new System.Drawing.Point(167, 60);
+ labelCopyright.Margin = new System.Windows.Forms.Padding(7, 0, 4, 0);
+ labelCopyright.MaximumSize = new System.Drawing.Size(0, 20);
+ labelCopyright.Name = "labelCopyright";
+ labelCopyright.Size = new System.Drawing.Size(316, 20);
+ labelCopyright.TabIndex = 21;
+ labelCopyright.Text = "Copyright";
+ labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // labelCompanyName
+ //
+ labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill;
+ labelCompanyName.Location = new System.Drawing.Point(167, 90);
+ labelCompanyName.Margin = new System.Windows.Forms.Padding(7, 0, 4, 0);
+ labelCompanyName.MaximumSize = new System.Drawing.Size(0, 20);
+ labelCompanyName.Name = "labelCompanyName";
+ labelCompanyName.Size = new System.Drawing.Size(316, 20);
+ labelCompanyName.TabIndex = 22;
+ labelCompanyName.Text = "Company Name";
+ labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // textBoxDescription
+ //
+ textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill;
+ textBoxDescription.Location = new System.Drawing.Point(167, 123);
+ textBoxDescription.Margin = new System.Windows.Forms.Padding(7, 3, 4, 3);
+ textBoxDescription.Multiline = true;
+ textBoxDescription.Name = "textBoxDescription";
+ textBoxDescription.ReadOnly = true;
+ textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ textBoxDescription.Size = new System.Drawing.Size(316, 147);
+ textBoxDescription.TabIndex = 23;
+ textBoxDescription.TabStop = false;
+ textBoxDescription.Text = "Description";
+ //
+ // okButton
+ //
+ okButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
+ okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ okButton.Location = new System.Drawing.Point(395, 277);
+ okButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ okButton.Name = "okButton";
+ okButton.Size = new System.Drawing.Size(88, 27);
+ okButton.TabIndex = 24;
+ okButton.Text = "&OK";
+ //
+ // AboutWindow
+ //
+ AcceptButton = okButton;
+ AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ ClientSize = new System.Drawing.Size(507, 327);
+ Controls.Add(tableLayoutPanel);
+ FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ MaximizeBox = false;
+ MinimizeBox = false;
+ Name = "AboutWindow";
+ Padding = new System.Windows.Forms.Padding(10);
+ ShowIcon = false;
+ ShowInTaskbar = false;
+ StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ Text = "AboutWindow";
+ tableLayoutPanel.ResumeLayout(false);
+ tableLayoutPanel.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)logoPictureBox).EndInit();
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+ private System.Windows.Forms.PictureBox logoPictureBox;
+ private System.Windows.Forms.Label labelProductName;
+ private System.Windows.Forms.Label labelVersion;
+ private System.Windows.Forms.Label labelCopyright;
+ private System.Windows.Forms.Label labelCompanyName;
+ private System.Windows.Forms.TextBox textBoxDescription;
+ private System.Windows.Forms.Button okButton;
+ }
+}
diff --git a/GUIApp/src/AboutWindow.cs b/GUIApp/src/AboutWindow.cs
new file mode 100644
index 0000000..b4f9868
--- /dev/null
+++ b/GUIApp/src/AboutWindow.cs
@@ -0,0 +1,93 @@
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace wit
+{
+ sealed partial class AboutWindow : Form
+ {
+ public AboutWindow()
+ {
+ InitializeComponent();
+ Text = "About: " + AssemblyTitle;
+ labelProductName.Text = "Program name: " + AssemblyProduct;
+ labelVersion.Text = $"Version: {AssemblyVersion}";
+ labelCopyright.Text = "Copyright: " + AssemblyCopyright;
+ labelCompanyName.Text = "Company: " + AssemblyCompany;
+ textBoxDescription.Text = "Description: " + AssemblyDescription;
+ }
+
+ #region Assembly Attribute Accessors
+
+ public static string AssemblyTitle
+ {
+ get
+ {
+ object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
+ if (attributes.Length > 0)
+ {
+ AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
+ if (titleAttribute.Title != "")
+ {
+ return titleAttribute.Title;
+ }
+ }
+ return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);
+ }
+ }
+
+ public static string? AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version?.ToString();
+
+ public static string AssemblyDescription
+ {
+ get
+ {
+ object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
+ if (attributes.Length == 0)
+ {
+ return "";
+ }
+ return ((AssemblyDescriptionAttribute)attributes[0]).Description;
+ }
+ }
+
+ public static string AssemblyProduct
+ {
+ get
+ {
+ object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
+ if (attributes.Length == 0)
+ {
+ return "";
+ }
+ return ((AssemblyProductAttribute)attributes[0]).Product;
+ }
+ }
+
+ public static string AssemblyCopyright
+ {
+ get
+ {
+ object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
+ if (attributes.Length == 0)
+ {
+ return "";
+ }
+ return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
+ }
+ }
+
+ public static string AssemblyCompany
+ {
+ get
+ {
+ object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
+ if (attributes.Length == 0)
+ {
+ return "";
+ }
+ return ((AssemblyCompanyAttribute)attributes[0]).Company;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/GUIApp/src/AboutWindow.resx b/GUIApp/src/AboutWindow.resx
new file mode 100644
index 0000000..6392ed1
--- /dev/null
+++ b/GUIApp/src/AboutWindow.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GUIApp/src/MainWindow.Designer.cs b/GUIApp/src/MainWindow.Designer.cs
new file mode 100644
index 0000000..43e54f0
--- /dev/null
+++ b/GUIApp/src/MainWindow.Designer.cs
@@ -0,0 +1,306 @@
+
+using System.Diagnostics.CodeAnalysis;
+using System.Windows.Forms;
+
+namespace wit
+{
+ partial class MainWindow
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ [RequiresUnreferencedCode("Calls System.ComponentModel.ComponentResourceManager.ApplyResources(Object, String)")]
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
+ InstallButton = new Button();
+ tableLayoutPanel1 = new TableLayoutPanel();
+ EfiDriveLabel = new Label();
+ DiskNumber = new NumericUpDown();
+ DestinationDriveLabel = new Label();
+ DestinationDrive = new ComboBox();
+ EfiDrive = new ComboBox();
+ RescanDisks = new Button();
+ WindowsEditionIndex = new NumericUpDown();
+ ImageFileLabel = new Label();
+ WindowsEditionIndexLabel = new Label();
+ ImageFilePath = new Label();
+ ChooseISOImage = new Button();
+ SourceDrive = new ComboBox();
+ DiskNumberLabel = new Label();
+ SourceDrive_Label = new Label();
+ SourceDrive_Scan = new Button();
+ ImageList = new DataGridView();
+ DiskList = new DataGridView();
+ MenuBar = new MenuStrip();
+ fileToolStripMenuItem = new ToolStripMenuItem();
+ exitToolStripMenuItem = new ToolStripMenuItem();
+ aboutToolStripMenuItem = new ToolStripMenuItem();
+ aboutTheProgramToolStripMenuItem = new ToolStripMenuItem();
+ saveFileDialog1 = new SaveFileDialog();
+ tableLayoutPanel1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)DiskNumber).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)WindowsEditionIndex).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)ImageList).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)DiskList).BeginInit();
+ MenuBar.SuspendLayout();
+ SuspendLayout();
+ //
+ // InstallButton
+ //
+ resources.ApplyResources(InstallButton, "InstallButton");
+ InstallButton.Name = "InstallButton";
+ InstallButton.UseVisualStyleBackColor = true;
+ InstallButton.Click += InstallButton_Click;
+ //
+ // tableLayoutPanel1
+ //
+ resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
+ tableLayoutPanel1.Controls.Add(EfiDriveLabel, 0, 1);
+ tableLayoutPanel1.Controls.Add(DiskNumber, 1, 2);
+ tableLayoutPanel1.Controls.Add(DestinationDriveLabel, 0, 0);
+ tableLayoutPanel1.Controls.Add(DestinationDrive, 1, 0);
+ tableLayoutPanel1.Controls.Add(EfiDrive, 1, 1);
+ tableLayoutPanel1.Controls.Add(RescanDisks, 2, 2);
+ tableLayoutPanel1.Controls.Add(WindowsEditionIndex, 1, 5);
+ tableLayoutPanel1.Controls.Add(ImageFileLabel, 0, 4);
+ tableLayoutPanel1.Controls.Add(WindowsEditionIndexLabel, 0, 5);
+ tableLayoutPanel1.Controls.Add(ImageFilePath, 1, 4);
+ tableLayoutPanel1.Controls.Add(ChooseISOImage, 2, 4);
+ tableLayoutPanel1.Controls.Add(SourceDrive, 1, 3);
+ tableLayoutPanel1.Controls.Add(DiskNumberLabel, 0, 2);
+ tableLayoutPanel1.Controls.Add(SourceDrive_Label, 0, 3);
+ tableLayoutPanel1.Controls.Add(SourceDrive_Scan, 2, 3);
+ tableLayoutPanel1.Name = "tableLayoutPanel1";
+ //
+ // EfiDriveLabel
+ //
+ resources.ApplyResources(EfiDriveLabel, "EfiDriveLabel");
+ EfiDriveLabel.FlatStyle = FlatStyle.System;
+ EfiDriveLabel.Name = "EfiDriveLabel";
+ //
+ // DiskNumber
+ //
+ DiskNumber.BorderStyle = BorderStyle.FixedSingle;
+ resources.ApplyResources(DiskNumber, "DiskNumber");
+ DiskNumber.Name = "DiskNumber";
+ //
+ // DestinationDriveLabel
+ //
+ resources.ApplyResources(DestinationDriveLabel, "DestinationDriveLabel");
+ DestinationDriveLabel.FlatStyle = FlatStyle.System;
+ DestinationDriveLabel.Name = "DestinationDriveLabel";
+ //
+ // DestinationDrive
+ //
+ resources.ApplyResources(DestinationDrive, "DestinationDrive");
+ DestinationDrive.DropDownStyle = ComboBoxStyle.DropDownList;
+ DestinationDrive.FormattingEnabled = true;
+ DestinationDrive.Name = "DestinationDrive";
+ //
+ // EfiDrive
+ //
+ resources.ApplyResources(EfiDrive, "EfiDrive");
+ EfiDrive.DropDownStyle = ComboBoxStyle.DropDownList;
+ EfiDrive.FormattingEnabled = true;
+ EfiDrive.Name = "EfiDrive";
+ //
+ // RescanDisks
+ //
+ resources.ApplyResources(RescanDisks, "RescanDisks");
+ RescanDisks.Name = "RescanDisks";
+ RescanDisks.UseVisualStyleBackColor = false;
+ RescanDisks.Click += RescanDisks_Click;
+ //
+ // WindowsEditionIndex
+ //
+ resources.ApplyResources(WindowsEditionIndex, "WindowsEditionIndex");
+ WindowsEditionIndex.BorderStyle = BorderStyle.FixedSingle;
+ WindowsEditionIndex.Name = "WindowsEditionIndex";
+ //
+ // ImageFileLabel
+ //
+ resources.ApplyResources(ImageFileLabel, "ImageFileLabel");
+ ImageFileLabel.FlatStyle = FlatStyle.System;
+ ImageFileLabel.Name = "ImageFileLabel";
+ //
+ // WindowsEditionIndexLabel
+ //
+ resources.ApplyResources(WindowsEditionIndexLabel, "WindowsEditionIndexLabel");
+ WindowsEditionIndexLabel.FlatStyle = FlatStyle.System;
+ WindowsEditionIndexLabel.Name = "WindowsEditionIndexLabel";
+ //
+ // ImageFilePath
+ //
+ resources.ApplyResources(ImageFilePath, "ImageFilePath");
+ ImageFilePath.AutoEllipsis = true;
+ ImageFilePath.FlatStyle = FlatStyle.System;
+ ImageFilePath.Name = "ImageFilePath";
+ //
+ // ChooseISOImage
+ //
+ resources.ApplyResources(ChooseISOImage, "ChooseISOImage");
+ ChooseISOImage.Name = "ChooseISOImage";
+ ChooseISOImage.UseVisualStyleBackColor = false;
+ ChooseISOImage.Click += ChooseImage_Click;
+ //
+ // SourceDrive
+ //
+ resources.ApplyResources(SourceDrive, "SourceDrive");
+ SourceDrive.DropDownStyle = ComboBoxStyle.DropDownList;
+ SourceDrive.FormattingEnabled = true;
+ SourceDrive.Name = "SourceDrive";
+ //
+ // DiskNumberLabel
+ //
+ resources.ApplyResources(DiskNumberLabel, "DiskNumberLabel");
+ DiskNumberLabel.FlatStyle = FlatStyle.System;
+ DiskNumberLabel.Name = "DiskNumberLabel";
+ //
+ // SourceDrive_Label
+ //
+ resources.ApplyResources(SourceDrive_Label, "SourceDrive_Label");
+ SourceDrive_Label.FlatStyle = FlatStyle.System;
+ SourceDrive_Label.Name = "SourceDrive_Label";
+ //
+ // SourceDrive_Scan
+ //
+ resources.ApplyResources(SourceDrive_Scan, "SourceDrive_Scan");
+ SourceDrive_Scan.Name = "SourceDrive_Scan";
+ SourceDrive_Scan.UseVisualStyleBackColor = false;
+ SourceDrive_Scan.Click += SourceDrive_Scan_Click;
+ //
+ // ImageList
+ //
+ ImageList.AllowUserToAddRows = false;
+ ImageList.AllowUserToDeleteRows = false;
+ ImageList.AllowUserToResizeColumns = false;
+ ImageList.AllowUserToResizeRows = false;
+ ImageList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
+ ImageList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
+ ImageList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ resources.ApplyResources(ImageList, "ImageList");
+ ImageList.Name = "ImageList";
+ ImageList.ReadOnly = true;
+ //
+ // DiskList
+ //
+ DiskList.AllowUserToAddRows = false;
+ DiskList.AllowUserToDeleteRows = false;
+ DiskList.AllowUserToResizeColumns = false;
+ DiskList.AllowUserToResizeRows = false;
+ DiskList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
+ DiskList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
+ DiskList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ resources.ApplyResources(DiskList, "DiskList");
+ DiskList.Name = "DiskList";
+ DiskList.ReadOnly = true;
+ DiskList.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
+ //
+ // MenuBar
+ //
+ MenuBar.BackColor = System.Drawing.Color.Transparent;
+ MenuBar.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, aboutToolStripMenuItem });
+ resources.ApplyResources(MenuBar, "MenuBar");
+ MenuBar.Name = "MenuBar";
+ MenuBar.RenderMode = ToolStripRenderMode.System;
+ //
+ // fileToolStripMenuItem
+ //
+ fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { exitToolStripMenuItem });
+ fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+ resources.ApplyResources(fileToolStripMenuItem, "fileToolStripMenuItem");
+ //
+ // exitToolStripMenuItem
+ //
+ exitToolStripMenuItem.Name = "exitToolStripMenuItem";
+ resources.ApplyResources(exitToolStripMenuItem, "exitToolStripMenuItem");
+ exitToolStripMenuItem.Click += CloseApplication;
+ //
+ // aboutToolStripMenuItem
+ //
+ aboutToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { aboutTheProgramToolStripMenuItem });
+ aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
+ resources.ApplyResources(aboutToolStripMenuItem, "aboutToolStripMenuItem");
+ //
+ // aboutTheProgramToolStripMenuItem
+ //
+ aboutTheProgramToolStripMenuItem.Name = "aboutTheProgramToolStripMenuItem";
+ resources.ApplyResources(aboutTheProgramToolStripMenuItem, "aboutTheProgramToolStripMenuItem");
+ aboutTheProgramToolStripMenuItem.Click += AboutWindow_Click;
+ //
+ // MainWindow
+ //
+ resources.ApplyResources(this, "$this");
+ AutoScaleMode = AutoScaleMode.Dpi;
+ Controls.Add(InstallButton);
+ Controls.Add(ImageList);
+ Controls.Add(tableLayoutPanel1);
+ Controls.Add(DiskList);
+ Controls.Add(MenuBar);
+ DoubleBuffered = true;
+ FormBorderStyle = FormBorderStyle.FixedDialog;
+ MaximizeBox = false;
+ Name = "MainWindow";
+ Load += MainWindow_Load;
+ tableLayoutPanel1.ResumeLayout(false);
+ tableLayoutPanel1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)DiskNumber).EndInit();
+ ((System.ComponentModel.ISupportInitialize)WindowsEditionIndex).EndInit();
+ ((System.ComponentModel.ISupportInitialize)ImageList).EndInit();
+ ((System.ComponentModel.ISupportInitialize)DiskList).EndInit();
+ MenuBar.ResumeLayout(false);
+ MenuBar.PerformLayout();
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+ private DataGridView DiskList;
+ private MenuStrip MenuBar;
+ private ToolStripMenuItem fileToolStripMenuItem;
+ private ToolStripMenuItem exitToolStripMenuItem;
+ private ToolStripMenuItem aboutToolStripMenuItem;
+ private Label DestinationDriveLabel;
+ private Label EfiDriveLabel;
+ private Button InstallButton;
+ private DataGridView ImageList;
+ private TableLayoutPanel tableLayoutPanel1;
+ private NumericUpDown WindowsEditionIndex;
+ private Label WindowsEditionIndexLabel;
+ private Button ChooseISOImage;
+ private Label ImageFilePath;
+ private Label DiskNumberLabel;
+ private NumericUpDown DiskNumber;
+ private Label ImageFileLabel;
+ private ToolStripMenuItem aboutTheProgramToolStripMenuItem;
+ private ComboBox DestinationDrive;
+ private ComboBox EfiDrive;
+ private Button RescanDisks;
+ private SaveFileDialog saveFileDialog1;
+ private Label SourceDrive_Label;
+ private Button SourceDrive_Scan;
+ private ComboBox SourceDrive;
+ }
+}
diff --git a/GUIApp/src/MainWindow.cs b/GUIApp/src/MainWindow.cs
new file mode 100644
index 0000000..29f2f74
--- /dev/null
+++ b/GUIApp/src/MainWindow.cs
@@ -0,0 +1,228 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.Versioning;
+using System.Windows.Forms;
+using WindowsInstallerLib;
+using WindowsInstallerLib.Helpers;
+
+namespace wit
+{
+ [SupportedOSPlatform("windows")]
+ public partial class MainWindow : Form
+ {
+ Parameters parameters = new()
+ {
+ DiskNumber = -1,
+ ImageIndex = -1
+ };
+
+ [RequiresUnreferencedCode("Calls System.ComponentModel.ComponentResourceManager.ApplyResources(Object, String)")]
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ private void MainWindow_Load(object sender, EventArgs e)
+ {
+ try
+ {
+ GetDisksData(sender, e);
+ GetDiskLetters(sender, e);
+
+ WindowsEditionIndex.Enabled = false;
+ InstallButton.Enabled = false;
+
+ DestinationDrive.SelectedIndexChanged += ValidateDiskLetter;
+ EfiDrive.SelectedIndexChanged += ValidateDiskLetter;
+ SourceDrive.SelectedIndexChanged += ValidateDiskLetter;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
+ private void CloseApplication(object sender, EventArgs e)
+ {
+ Application.Exit();
+ }
+
+ private void ChooseImage_Click(object sender, EventArgs e)
+ {
+ SourceDrive_Scan.Enabled = false;
+
+ if (ImageFilePath.Text == "No image file is selected.")
+ {
+ OpenFileDialog OpenFileDialog = new()
+ {
+ Filter = "ESD file (*.esd)|*.esd|WIM file (*.wim)|*.wim",
+ CheckFileExists = true,
+ CheckPathExists = true,
+ AddExtension = true,
+ };
+
+ DialogResult DialogResult = OpenFileDialog.ShowDialog();
+
+ if (DialogResult == DialogResult.Cancel)
+ {
+ SourceDrive_Label.Enabled = true;
+ return;
+ }
+
+ if (string.IsNullOrWhiteSpace(OpenFileDialog.FileName))
+ {
+ MessageBox.Show("No image file was selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ SourceDrive_Scan.Enabled = true;
+ ImageFilePath.Text = "No image file is selected";
+ return;
+ }
+
+ if (!OpenFileDialog.FileName.Contains("install"))
+ {
+ MessageBox.Show("Invalid image file. It must be 'install.wim' or 'install.esd'.", "Invalid file", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ SourceDrive_Scan.Enabled = true;
+ throw new InvalidDataException("Invalid image file. It must be 'install.wim' or 'install.esd'.");
+ }
+
+ parameters.ImageFilePath = OpenFileDialog.FileName;
+ ImageFilePath.Text = parameters.ImageFilePath;
+ SourceDrive.SelectedItem = Path.GetPathRoot(ImageFilePath.Text?.TrimEnd('\\'));
+ }
+
+ if (ImageList.Columns.Count >= 1)
+ {
+ ImageList.Columns.Clear();
+ }
+
+ try
+ {
+ GetImageInfo(sender, e);
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ private void SourceDrive_Scan_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ if (SourceDrive.Text.Length > 0)
+ {
+ foreach (string file in Directory.EnumerateFiles(SourceDrive.Text + @"\sources\"))
+ {
+ if (file.Contains("install") && file.EndsWith(".esd", StringComparison.CurrentCulture) ||
+ file.Contains("install") && file.EndsWith(".wim", StringComparison.CurrentCulture))
+ {
+ ImageFilePath.Text = file;
+ parameters.ImageFilePath = ImageFilePath.Text;
+ ChooseISOImage.Enabled = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ MessageBox.Show("Please select a source drive.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+
+ if (ImageList.Columns.Count >= 1)
+ {
+ ImageList.Columns.Clear();
+ }
+
+ GetImageInfo(sender, e);
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
+ private void InstallButton_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ parameters.DestinationDrive = DestinationDrive.Text;
+ parameters.EfiDrive = EfiDrive.Text;
+ parameters.DiskNumber = Convert.ToInt32(DiskNumber.Value);
+ parameters.ImageFilePath = ImageFilePath.Text;
+ parameters.ImageIndex = Convert.ToInt32(WindowsEditionIndex.Value);
+
+ if (string.IsNullOrWhiteSpace(parameters.FirmwareType))
+ {
+ switch (SystemInfo.SystemSupportsEFI())
+ {
+ case true:
+ parameters.FirmwareType = "UEFI";
+ break;
+ case false:
+ parameters.FirmwareType = "BIOS";
+ break;
+ }
+ }
+ }
+ catch
+ {
+ throw;
+ }
+
+ try
+ {
+ InstallButton.Text = "Please wait...";
+ Deployment.FormatDisk(ref parameters);
+ Deployment.ApplyImage(ref parameters);
+ Deployment.InstallBootloader(ref parameters);
+ InstallButton.Text = "Installation complete";
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ private void AboutWindow_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ new AboutWindow().ShowDialog(this);
+ }
+ catch (ArgumentException)
+ {
+ throw;
+ }
+ catch (InvalidOperationException)
+ {
+ throw;
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ private void RescanDisks_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ RescanDisks.Text = "Please wait...";
+ RescanDisks.Enabled = false;
+ DiskList.Columns.Clear();
+ DiskList.Rows.Clear();
+ GetDisksData(sender, e);
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ RescanDisks.Text = "Rescan disks";
+ RescanDisks.Enabled = true;
+ }
+ }
+ }
+}
diff --git a/GUIApp/src/MainWindow.resx b/GUIApp/src/MainWindow.resx
new file mode 100644
index 0000000..df2c877
--- /dev/null
+++ b/GUIApp/src/MainWindow.resx
@@ -0,0 +1,813 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ True
+
+
+
+ System
+
+
+ NoControl
+
+
+
+ 668, 206
+
+
+ 104, 27
+
+
+ 4
+
+
+ Install Windows
+
+
+ InstallButton
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ True
+
+
+ Single
+
+
+ 3
+
+
+ Top, Bottom, Left, Right
+
+
+ True
+
+
+ 4, 31
+
+
+ 96, 29
+
+
+ 3
+
+
+ Bootloader drive
+
+
+ EfiDriveLabel
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 0
+
+
+ 107, 64
+
+
+ 41, 23
+
+
+ 7
+
+
+ DiskNumber
+
+
+ System.Windows.Forms.NumericUpDown, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 1
+
+
+ Top, Bottom, Left, Right
+
+
+ True
+
+
+ 4, 1
+
+
+ 96, 29
+
+
+ 2
+
+
+ OS drive
+
+
+ DestinationDriveLabel
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 2
+
+
+ Left
+
+
+ System
+
+
+ 107, 4
+
+
+ 41, 23
+
+
+ 14
+
+
+ DestinationDrive
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 3
+
+
+ Left
+
+
+ System
+
+
+ 107, 34
+
+
+ 41, 23
+
+
+ 15
+
+
+ EfiDrive
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 4
+
+
+ Top, Bottom, Left, Right
+
+
+ GrowAndShrink
+
+
+ System
+
+
+ NoControl
+
+
+ 252, 64
+
+
+ 118, 24
+
+
+ 16
+
+
+ Rescan devices
+
+
+ RescanDisks
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 5
+
+
+ True
+
+
+ 107, 157
+
+
+ 41, 23
+
+
+ 10
+
+
+ WindowsEditionIndex
+
+
+ System.Windows.Forms.NumericUpDown, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 6
+
+
+ True
+
+
+ Fill
+
+
+ NoControl
+
+
+ 4, 123
+
+
+ 96, 30
+
+
+ 8
+
+
+ Image file
+
+
+ ImageFileLabel
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 7
+
+
+ True
+
+
+ NoControl
+
+
+ 4, 154
+
+
+ 96, 15
+
+
+ 11
+
+
+ Windows edition
+
+
+ WindowsEditionIndexLabel
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 8
+
+
+ Top, Bottom, Left, Right
+
+
+ True
+
+
+ NoControl
+
+
+ 107, 123
+
+
+ 138, 30
+
+
+ 13
+
+
+ No image file is selected.
+
+
+ MiddleCenter
+
+
+ ImageFilePath
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 9
+
+
+ Top, Bottom, Left, Right
+
+
+ GrowAndShrink
+
+
+ System
+
+
+ NoControl
+
+
+ 252, 126
+
+
+ 118, 24
+
+
+ 12
+
+
+ Choose ISO image
+
+
+ ChooseISOImage
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 10
+
+
+ Left
+
+
+ System
+
+
+ 107, 95
+
+
+ 41, 23
+
+
+ 17
+
+
+ SourceDrive
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 11
+
+
+ Top, Bottom, Left, Right
+
+
+ True
+
+
+ NoControl
+
+
+ 4, 61
+
+
+ 96, 30
+
+
+ 6
+
+
+ Storage device
+
+
+ DiskNumberLabel
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 12
+
+
+ True
+
+
+ Fill
+
+
+ NoControl
+
+
+ 4, 92
+
+
+ 96, 30
+
+
+ 18
+
+
+ Source drive
+
+
+ SourceDrive_Label
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 13
+
+
+ Top, Bottom, Left, Right
+
+
+ GrowAndShrink
+
+
+ System
+
+
+ NoControl
+
+
+ 252, 95
+
+
+ 118, 24
+
+
+ 19
+
+
+ Scan source drive
+
+
+ SourceDrive_Scan
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 14
+
+
+ 12, 27
+
+
+ 6
+
+
+ 374, 206
+
+
+ 5
+
+
+ tableLayoutPanel1
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="EfiDriveLabel" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="DiskNumber" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="DestinationDriveLabel" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="DestinationDrive" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="EfiDrive" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="RescanDisks" Row="2" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="WindowsEditionIndex" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="ImageFileLabel" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="WindowsEditionIndexLabel" Row="5" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="ImageFilePath" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="ChooseISOImage" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceDrive" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="DiskNumberLabel" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="SourceDrive_Label" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="SourceDrive_Scan" Row="3" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,Absolute,30,AutoSize,0,Absolute,20" /></TableLayoutSettings>
+
+
+ 12, 239
+
+
+ Vertical
+
+
+ 760, 152
+
+
+ 4
+
+
+ ImageList
+
+
+ System.Windows.Forms.DataGridView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ 12, 397
+
+
+ 760, 152
+
+
+ 0
+
+
+ DiskList
+
+
+ System.Windows.Forms.DataGridView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ 17, 17
+
+
+ 92, 22
+
+
+ Exit
+
+
+ 37, 20
+
+
+ File
+
+
+ 176, 22
+
+
+ About the program
+
+
+ 52, 20
+
+
+ About
+
+
+ 0, 0
+
+
+ 784, 24
+
+
+ 1
+
+
+ Menu
+
+
+ MenuBar
+
+
+ System.Windows.Forms.MenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 4
+
+
+ 119, 17
+
+
+ True
+
+
+ 96, 96
+
+
+ True
+
+
+ True
+
+
+ GrowAndShrink
+
+
+ 784, 561
+
+
+ 800, 600
+
+
+ 800, 600
+
+
+ Windows Installer
+
+
+ fileToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ exitToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ aboutToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ aboutTheProgramToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ saveFileDialog1
+
+
+ System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ MainWindow
+
+
+ System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GUIApp/src/Program.cs b/GUIApp/src/Program.cs
new file mode 100644
index 0000000..ee1952d
--- /dev/null
+++ b/GUIApp/src/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Windows.Forms;
+
+namespace wit
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ [RequiresUnreferencedCode("Calls wit.MainWindow.MainWindow()")]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new MainWindow());
+ }
+ }
+}
diff --git a/GUIApp/src/Utilities.cs b/GUIApp/src/Utilities.cs
new file mode 100644
index 0000000..6f2c7a7
--- /dev/null
+++ b/GUIApp/src/Utilities.cs
@@ -0,0 +1,142 @@
+using Microsoft.Dism;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Windows.Forms;
+using WindowsInstallerLib.Helpers;
+
+namespace wit
+{
+ public partial class MainWindow
+ {
+ private void GetDiskLetters(object sender, EventArgs e)
+ {
+ List DiskLetters = [
+ "A:\\",
+ "B:\\",
+ "C:\\",
+ "D:\\",
+ "E:\\",
+ "F:\\",
+ "G:\\",
+ "H:\\",
+ "I:\\",
+ "J:\\",
+ "K:\\",
+ "L:\\",
+ "M:\\",
+ "N:\\",
+ "O:\\",
+ "P:\\",
+ "Q:\\",
+ "R:\\",
+ "S:\\",
+ "T:\\",
+ "U:\\",
+ "V:\\",
+ "W:\\",
+ "X:\\",
+ "Y:\\",
+ "Z:\\"
+ ];
+ List DiskLettersToRemove = [];
+ List> Disks = Devices.GetDisks();
+
+ try
+ {
+ foreach (string DiskLetter in DiskLetters)
+ {
+ foreach (Tuple disk in Disks)
+ {
+ string Letter = disk.Item3 + @"\";
+
+ if (DiskLetter.Equals(Letter, StringComparison.Ordinal))
+ {
+ DiskLettersToRemove.Add(Letter);
+ }
+ }
+ }
+
+ foreach (string DiskLetter in DiskLettersToRemove)
+ {
+ DiskLetters.Remove(DiskLetter);
+ }
+
+ DestinationDrive.Items.AddRange(DiskLetters.ToArray());
+ EfiDrive.Items.AddRange(DiskLetters.ToArray());
+ SourceDrive.Items.AddRange(DiskLetters.ToArray());
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
+ private void GetDisksData(object sender, EventArgs e)
+ {
+ DiskList.Columns.Add("DiskNumber", "Disk");
+ DiskList.Columns.Add("Model", "Model");
+ DiskList.Columns.Add("Label", "Label");
+
+ List> disks = Devices.GetDisks();
+
+ foreach (Tuple disk in disks)
+ {
+ try
+ {
+ DiskList.Rows.Add(disk.Item1, disk.Item2, disk.Item3);
+ }
+ catch (ArgumentNullException)
+ {
+ throw;
+ }
+ catch (InvalidOperationException)
+ {
+ throw;
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ DiskList.Sort(DiskList.Columns[0], ListSortDirection.Ascending);
+ DiskList.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
+ DiskNumber.Maximum = DiskList.Rows.Count - 1;
+ }
+
+ private void GetImageInfo(object sender, EventArgs e)
+ {
+ try
+ {
+ DismImageInfoCollection imageInfoCollection = Deployment.GetImageInfo(ref parameters);
+
+ WindowsEditionIndex.Minimum = 1;
+ WindowsEditionIndex.Maximum = imageInfoCollection.Count;
+
+ WindowsEditionIndex.Enabled = true;
+
+ ImageList.Columns.Add("Index", "Index");
+ ImageList.Columns.Add("Edition", "Name");
+ ImageList.Columns.Add("Version", "Version");
+
+ foreach (DismImageInfo DismImage in imageInfoCollection)
+ {
+ ImageList.Rows.Add(DismImage.ImageIndex, DismImage.ImageName, DismImage.ProductVersion);
+ }
+ }
+ catch (DismException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ finally
+ {
+ DismApi.Shutdown();
+ }
+ }
+ }
+}
diff --git a/GUIApp/src/ValidateDiskLetter.cs b/GUIApp/src/ValidateDiskLetter.cs
new file mode 100644
index 0000000..8e5be60
--- /dev/null
+++ b/GUIApp/src/ValidateDiskLetter.cs
@@ -0,0 +1,71 @@
+using System.Windows.Forms;
+using System;
+
+namespace wit
+{
+ public partial class MainWindow
+ {
+ private static void ShowMessage(string text, string caption)
+ {
+ try
+ {
+ MessageBox.Show(text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ catch
+ {
+ throw;
+ }
+ }
+
+ private void ValidateDiskLetter(object? sender, EventArgs e)
+ {
+ if (DestinationDrive.Text.Length > 0)
+ {
+ if (DestinationDrive.Text == EfiDrive.Text)
+ {
+ ShowMessage("The OS drive letter cannot be the same as the bootloader drive.", "Duplicate letter");
+ DestinationDrive.Text = null;
+ EfiDrive.Text = null;
+ }
+ else if (DestinationDrive.Text == SourceDrive.Text)
+ {
+ ShowMessage("The OS drive letter cannot be the same as the source drive.", "Duplicate letter");
+ DestinationDrive.Text = null;
+ SourceDrive.Text = null;
+ }
+ }
+
+ if (EfiDrive.Text.Length > 0)
+ {
+ if (EfiDrive.Text == DestinationDrive.Text)
+ {
+ ShowMessage("The bootloader drive letter cannot be the same as the OS drive.", "Duplicate letter");
+ EfiDrive.Text = null;
+ DestinationDrive.Text = null;
+ }
+ else if (EfiDrive.Text == SourceDrive.Text)
+ {
+ ShowMessage("The bootloader drive letter cannot be the same as the source drive.", "Duplicate letter");
+ EfiDrive.Text = null;
+ SourceDrive.Text = null;
+ }
+ }
+
+ if (SourceDrive.Text.Length > 0)
+ {
+ if (SourceDrive.Text == DestinationDrive.Text)
+ {
+ ShowMessage("The source drive letter cannot be the same as the OS drive.", "Duplicate letter");
+ SourceDrive.Text = null;
+ DestinationDrive.Text = null;
+ }
+ else if (SourceDrive.Text == EfiDrive.Text)
+ {
+ ShowMessage("The source drive letter cannot be the same as the bootloader drive.", "Duplicate letter");
+ SourceDrive.Text = null;
+ EfiDrive.Text = null;
+ }
+ }
+ }
+ }
+}
diff --git a/Windows Installer.sln b/Windows Installer.sln
index d2766a2..629e65d 100644
--- a/Windows Installer.sln
+++ b/Windows Installer.sln
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "ConsoleApp\Co
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsInstallerLib", "WindowsInstallerLib\WindowsInstallerLib.csproj", "{0621F1C4-7D92-4863-8BF3-39E2D8D0661C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GUIApp", "GUIApp\GUIApp.csproj", "{DEB8CFC7-E65A-B638-0B78-5385B78C1865}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -21,6 +23,10 @@ Global
{0621F1C4-7D92-4863-8BF3-39E2D8D0661C}.Debug|x64.Build.0 = Debug|x64
{0621F1C4-7D92-4863-8BF3-39E2D8D0661C}.Release|x64.ActiveCfg = Release|x64
{0621F1C4-7D92-4863-8BF3-39E2D8D0661C}.Release|x64.Build.0 = Release|x64
+ {DEB8CFC7-E65A-B638-0B78-5385B78C1865}.Debug|x64.ActiveCfg = Debug|x64
+ {DEB8CFC7-E65A-B638-0B78-5385B78C1865}.Debug|x64.Build.0 = Debug|x64
+ {DEB8CFC7-E65A-B638-0B78-5385B78C1865}.Release|x64.ActiveCfg = Release|x64
+ {DEB8CFC7-E65A-B638-0B78-5385B78C1865}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/WindowsInstallerLib/WindowsInstallerLib.csproj b/WindowsInstallerLib/WindowsInstallerLib.csproj
index 3969d30..4965f4d 100644
--- a/WindowsInstallerLib/WindowsInstallerLib.csproj
+++ b/WindowsInstallerLib/WindowsInstallerLib.csproj
@@ -8,7 +8,7 @@
none
$(AssemblyName)
latest
- 1.1.4.0
+ 1.1.5.0
x64
true
diff --git a/WindowsInstallerLib/src/DeployManager.cs b/WindowsInstallerLib/src/DeployManager.cs
index 1b9e272..0f97d1f 100644
--- a/WindowsInstallerLib/src/DeployManager.cs
+++ b/WindowsInstallerLib/src/DeployManager.cs
@@ -1,5 +1,6 @@
using Microsoft.Dism;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Runtime.Versioning;
@@ -282,6 +283,60 @@ internal static void GetImageInfo(ref Parameters parameters)
}
}
+ ///
+ /// Gets all Windows editions available using DISM, if any, and returns them as a collection.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static DismImageInfoCollection GetImageInfoD(ref Parameters parameters)
+ {
+ List> TransitionalTuple = [];
+
+ ArgumentException.ThrowIfNullOrEmpty(parameters.ImageFilePath, nameof(parameters.ImageFilePath));
+
+ if (!PrivilegesManager.IsAdmin())
+ {
+ throw new UnauthorizedAccessException("You do not have enough privileges to initialize the DISM API.");
+ }
+
+ try
+ {
+ DismApi.Initialize(DismLogLevel.LogErrorsWarnings);
+
+ DismImageInfoCollection images = DismApi.GetImageInfo(parameters.ImageFilePath);
+
+ switch (images.Count)
+ {
+ case > 1:
+ Console.WriteLine($"\nFound {images.Count} images in {parameters.ImageFilePath}, shown below.\n", ConsoleColor.Yellow);
+ break;
+ case 1:
+ Console.WriteLine($"\nFound {images.Count} image in {parameters.ImageFilePath}, shown below.\n", ConsoleColor.Yellow);
+ break;
+ case 0:
+ Console.WriteLine($"\nNo images were found in {parameters.ImageFilePath}\n", ConsoleColor.Red);
+ throw new InvalidDataException($"images.Count is {images.Count}. This is considered to be invalid, the program cannot continue.");
+ }
+
+ return images;
+ }
+ catch (DismException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ finally
+ {
+ DismApi.Shutdown();
+ }
+ }
+
///
/// Retrieves information about the images contained in the specified image file.
///
@@ -337,49 +392,35 @@ internal static DismImageInfoCollection GetImageInfoT(ref Parameters parameters)
///
internal static void InstallAdditionalDrivers(ref Parameters parameters)
{
+ bool IS_ADMIN = PrivilegesManager.IsAdmin();
+
DismSession? session = null;
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.AdditionalDriversDrive, nameof(parameters));
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.AdditionalDrive, nameof(parameters));
- if (!PrivilegesManager.IsAdmin())
+ switch (IS_ADMIN)
{
- throw new UnauthorizedAccessException("You do not have enough privileges to install additional drivers.");
+ case true:
+ try
+ {
+ DismApi.Initialize(DismLogLevel.LogErrorsWarnings);
+ }
+ catch (DismException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ break;
+ case false:
+ throw new UnauthorizedAccessException("You do not have enough privileges to initialize the DISM API.");
}
try
{
- switch (PrivilegesManager.IsAdmin())
- {
- case true:
- try
- {
- DismApi.Initialize(DismLogLevel.LogErrorsWarnings);
- }
- catch (DismException)
- {
- throw;
- }
- catch (Exception)
- {
- throw;
- }
- break;
- case false:
- throw new UnauthorizedAccessException("You do not have enough privileges to initialize the DISM API.");
- }
-
- try
- {
- session ??= DismApi.OpenOfflineSession(parameters.DestinationDrive);
- }
- catch (DismException)
- {
- throw;
- }
- catch (Exception)
- {
- throw;
- }
+ session ??= DismApi.OpenOfflineSession(parameters.DestinationDrive);
}
catch (DismException)
{
@@ -392,7 +433,7 @@ internal static void InstallAdditionalDrivers(ref Parameters parameters)
try
{
- DismApi.AddDriversEx(session, parameters.AdditionalDriversDrive, false, true);
+ DismApi.AddDriversEx(session, parameters.AdditionalDrive, false, true);
}
finally
{
@@ -416,9 +457,11 @@ internal static void InstallAdditionalDrivers(ref Parameters parameters)
/// Thrown if the current process does not have administrative privileges required to perform the installation.
internal static int InstallBootloader(ref Parameters parameters)
{
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.DestinationDrive, nameof(parameters.DestinationDrive));
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.EfiDrive, nameof(parameters.EfiDrive));
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.FirmwareType, nameof(parameters.FirmwareType));
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.DestinationDrive, nameof(parameters));
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.EfiDrive, nameof(parameters));
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.FirmwareType, nameof(parameters));
+
+ bool IS_ADMIN = PrivilegesManager.IsAdmin();
string EFI_BOOT_PATH = Path.Join(parameters.EfiDrive, @"\EFI\Boot");
string EFI_MICROSOFT_PATH = Path.Join(parameters.EfiDrive, @"\EFI\Microsoft");
@@ -428,7 +471,7 @@ internal static int InstallBootloader(ref Parameters parameters)
bool EFI_MICROSOFT_EXISTS = Directory.Exists(EFI_MICROSOFT_PATH);
bool WINDIR_EXISTS = Directory.Exists(WINDIR_PATH);
- if (!PrivilegesManager.IsAdmin())
+ if (!IS_ADMIN)
{
throw new UnauthorizedAccessException($"You do not have enough privileges to install the bootloader to {parameters.EfiDrive}");
}
@@ -445,9 +488,8 @@ internal static int InstallBootloader(ref Parameters parameters)
throw new DirectoryNotFoundException(@$"The directory {WINDIR_PATH} does not exist!");
}
- Console.WriteLine($"Firmware type is set to: {parameters.FirmwareType}");
Console.WriteLine($"\n==> Installing bootloader to drive {parameters.EfiDrive} in disk {parameters.DiskNumber}");
- ProcessManager.StartCmdProcess("bcdboot", @$"{WINDIR_PATH} /s {parameters.EfiDrive} /f {parameters.FirmwareType}");
+ ProcessManager.StartCmdProcess("bcdboot.exe", @$"{WINDIR_PATH} /s {parameters.EfiDrive} /f {parameters.FirmwareType}");
}
catch (IOException)
{
@@ -457,7 +499,6 @@ internal static int InstallBootloader(ref Parameters parameters)
{
throw;
}
-
return ProcessManager.ExitCode;
}
}
diff --git a/WindowsInstallerLib/src/DiskManager.cs b/WindowsInstallerLib/src/DiskManager.cs
index 7f4780f..7b4cae6 100644
--- a/WindowsInstallerLib/src/DiskManager.cs
+++ b/WindowsInstallerLib/src/DiskManager.cs
@@ -1,7 +1,10 @@
using System;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Management;
+using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
namespace WindowsInstallerLib
@@ -43,27 +46,22 @@ internal static int FormatDisk(ref Parameters parameters)
}
}
- ///
- /// Lists all disk drives on the system and displays their details, including disk number, model, and device ID.
- ///
- /// This method queries the system's disk drives using WMI (Windows Management
- /// Instrumentation) and outputs the retrieved information to the console. The details include the disk number,
- /// model, and device ID for each disk drive found. Note that this method is intended for internal use
- /// and writes directly to the console. It does not return the retrieved data or provide a way to
- /// programmatically access it.
- internal static void ListAll()
+ internal static List> GetDisks()
{
+ List> DisksList = [];
try
{
WqlObjectQuery DeviceTable = new("SELECT * FROM Win32_DiskDrive");
ManagementObjectSearcher DeviceInfo = new(DeviceTable);
foreach (ManagementObject o in DeviceInfo.Get().Cast())
{
- Console.WriteLine("Disk number = " + o["Index"]);
- Console.WriteLine("Model = " + o["Model"]);
- Console.WriteLine("DeviceID = " + o["DeviceID"]);
- Console.WriteLine("");
+ int Index = Convert.ToInt32(o["Index"]);
+ string Model = o["Model"].ToString() ?? string.Empty;
+ string Letter = GetDiskLetter(o["DeviceID"]);
+
+ DisksList.Add(new(Index, Model, Letter));
}
+ return DisksList;
}
catch (Exception)
{
@@ -71,30 +69,68 @@ internal static void ListAll()
}
}
- ///
- /// Retrieves an array of all available drive information on the system.
- ///
- /// An array of objects representing the drives available on the system.
- internal static DriveInfo[] GetDisksT()
+ private static string GetDiskLetter(object DeviceID)
{
+ string DriveLetter = string.Empty;
+
+ ArgumentNullException.ThrowIfNull(DeviceID);
+
try
{
- DriveInfo[] drives = DriveInfo.GetDrives();
-
- return drives;
+ WqlObjectQuery PartitionQuery = new($"ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{DeviceID}'}} WHERE AssocClass=Win32_DiskDriveToDiskPartition");
+ ManagementObjectSearcher PartitionSearcher = new(PartitionQuery);
+ foreach (ManagementObject partition in PartitionSearcher.Get().Cast())
+ {
+ WqlObjectQuery LogicalDiskQuery = new($"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{partition["DeviceID"]}'}} WHERE AssocClass=Win32_LogicalDiskToPartition");
+ ManagementObjectSearcher LogicalDiskSearcher = new(LogicalDiskQuery);
+ foreach (ManagementObject logicalDisk in LogicalDiskSearcher.Get().Cast())
+ {
+ DriveLetter = logicalDisk["DeviceID"].ToString() ?? throw new ArgumentNullException("DeviceID cannot be null", DeviceID.ToString());
+ }
+ }
}
- catch (IOException)
+ catch (Exception)
{
throw;
}
- catch (UnauthorizedAccessException)
+ return DriveLetter;
+ }
+
+
+ ///
+ /// Lists all disk drives on the system and displays their details, including disk number, model, and device ID.
+ ///
+ /// This method queries the system's disk drives using WMI (Windows Management
+ /// Instrumentation) and outputs the retrieved information to the console. The details include the disk number,
+ /// model, and device ID for each disk drive found. Note that this method is intended for internal use
+ /// and writes directly to the console. It does not return the retrieved data or provide a way to
+ /// programmatically access it.
+ internal static SortedDictionary GetDisks()
+ {
+ SortedDictionary SystemDisks = [];
+
+ try
{
- throw;
+ WqlObjectQuery Query = new("SELECT * FROM Win32_DiskDrive");
+ ManagementObjectSearcher ObjectSearcher = new(Query);
+ foreach (ManagementObject obj in ObjectSearcher.Get().Cast())
+ {
+ int Index = Convert.ToInt32(obj["Index"], CultureInfo.CurrentCulture);
+ string? Model = obj["Model"].ToString();
+
+ if (Model != null)
+ {
+ SystemDisks.Add(Index, Model);
+ }
+ }
+
}
catch (Exception)
{
throw;
}
+
+ return SystemDisks;
}
}
}
diff --git a/WindowsInstallerLib/src/Helpers.cs b/WindowsInstallerLib/src/Helpers.cs
new file mode 100644
index 0000000..4364311
--- /dev/null
+++ b/WindowsInstallerLib/src/Helpers.cs
@@ -0,0 +1,33 @@
+using Microsoft.Dism;
+using System;
+using System.Collections.Generic;
+
+namespace WindowsInstallerLib
+{
+ namespace Helpers
+ {
+ public class Privileges
+ {
+ public static bool IsAdmin() { return PrivilegesManager.IsAdmin(); }
+ }
+
+ public class Devices
+ {
+ public static List> GetDisks() { return DiskManager.GetDisks(); }
+ }
+
+ public class SystemInfo
+ {
+ public static bool SystemSupportsEFI() { return SystemInfoManager.IsEFI(); }
+ }
+
+ public class Deployment
+ {
+ public static int ExitCode { get; private set; }
+ public static DismImageInfoCollection GetImageInfo(ref Parameters parameters) { return DeployManager.GetImageInfoD(ref parameters); }
+ public static void FormatDisk(ref Parameters parameters) { DiskManager.FormatDisk(ref parameters); }
+ public static void ApplyImage(ref Parameters parameters) { DeployManager.ApplyImage(ref parameters); }
+ public static void InstallBootloader(ref Parameters parameters) { DeployManager.InstallBootloader(ref parameters); }
+ }
+ }
+}
diff --git a/WindowsInstallerLib/src/InstallerManager.cs b/WindowsInstallerLib/src/InstallerManager.cs
index 5107214..228f0dc 100644
--- a/WindowsInstallerLib/src/InstallerManager.cs
+++ b/WindowsInstallerLib/src/InstallerManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.Versioning;
@@ -17,7 +18,7 @@ namespace WindowsInstallerLib
/// Gets or sets the source drive containing the data to be imaged.
/// Gets or sets the index of the image within the image file to be applied.
/// Gets or sets the file path of the image file to be used in the operation.
- /// Gets or sets a value indicating whether additional drivers should be installed during the imaging process.
+ /// Gets or sets a value indicating whether additional drivers should be installed during the imaging process.
/// Gets or sets the firmware type of the system being imaged.
[SupportedOSPlatform("windows")]
public struct Parameters(string DestinationDrive,
@@ -26,7 +27,7 @@ public struct Parameters(string DestinationDrive,
string SourceDrive,
int ImageIndex,
string ImageFilePath,
- string AdditionalDriversDrive,
+ string AdditionalDrive,
string FirmwareType)
{
public string DestinationDrive { get; set; } = DestinationDrive;
@@ -35,7 +36,7 @@ public struct Parameters(string DestinationDrive,
public string SourceDrive { get; set; } = SourceDrive;
public int ImageIndex { get; set; } = ImageIndex;
public string ImageFilePath { get; set; } = ImageFilePath;
- public string AdditionalDriversDrive { get; set; } = AdditionalDriversDrive;
+ public string AdditionalDrive { get; set; } = AdditionalDrive;
public string FirmwareType { get; set; } = FirmwareType;
}
@@ -62,15 +63,14 @@ public sealed class InstallerManager
public static void Configure(ref Parameters parameters)
{
#region DestinationDrive
- if (string.IsNullOrEmpty(parameters.DestinationDrive) ||
- string.IsNullOrWhiteSpace(parameters.DestinationDrive))
+ if (string.IsNullOrWhiteSpace(parameters.DestinationDrive))
{
- string p_DestinationDrive;
-
Console.Write("\n==> Type the mountpoint to use for deploying Windows (e.g. Z:): ");
+
try
{
- p_DestinationDrive = Console.ReadLine() ?? throw new ArgumentNullException(nameof(parameters), "DestinationDrive is null!");
+ parameters.DestinationDrive = Console.ReadLine() ??
+ throw new ArgumentException("A valid destination drive is required.", nameof(parameters));
}
catch (IOException)
{
@@ -89,35 +89,28 @@ public static void Configure(ref Parameters parameters)
throw;
}
- ArgumentException.ThrowIfNullOrWhiteSpace(p_DestinationDrive);
-
- if (p_DestinationDrive.Length != 2 ||
- p_DestinationDrive.Length > 2)
+ if (parameters.DestinationDrive.Length > 2 ||
+ parameters.DestinationDrive.Length < 2)
{
- throw new ArgumentException(@$"Invalid source drive {p_DestinationDrive}. Too many characters.");
+ throw new ArgumentException($"Invalid destination drive {parameters.DestinationDrive}.");
}
- if (p_DestinationDrive.StartsWith(':') ||
- !p_DestinationDrive.EndsWith(':'))
+ if (parameters.DestinationDrive.StartsWith(':') || !parameters.DestinationDrive.EndsWith(':'))
{
- throw new InvalidDataException(@$"Invalid source drive {p_DestinationDrive}. A valid drive is for example: 'Z:'.");
+ throw new InvalidDataException($"Invalid source drive {parameters.DestinationDrive}.");
}
-
- parameters.DestinationDrive = p_DestinationDrive;
}
#endregion
#region EfiDrive
- if (string.IsNullOrEmpty(parameters.EfiDrive) ||
- string.IsNullOrWhiteSpace(parameters.EfiDrive))
+ if (string.IsNullOrWhiteSpace(parameters.EfiDrive))
{
- string p_EfiDrive;
-
Console.Write("\n==> Type the mountpoint to use for the bootloader (e.g. Y:): ");
try
{
- p_EfiDrive = Console.ReadLine() ?? throw new ArgumentNullException(nameof(parameters), "EfiDrive is null!"); ;
+ parameters.EfiDrive = Console.ReadLine() ??
+ throw new ArgumentException("A valid EFI drive is required.", nameof(parameters));
}
catch (IOException)
{
@@ -136,32 +129,31 @@ public static void Configure(ref Parameters parameters)
throw;
}
- ArgumentException.ThrowIfNullOrWhiteSpace(p_EfiDrive);
-
- if (p_EfiDrive.StartsWith(':'))
+ if (parameters.EfiDrive.StartsWith(':'))
{
- throw new ArgumentException(@$"Invalid EFI drive {p_EfiDrive}, it must have a colon at the end not at the beginning. For example: 'Y:'.");
+ throw new ArgumentException(@$"Invalid EFI drive {parameters.EfiDrive}, it must have a colon at the end not at the beginning. For example: 'Y:'.");
}
- else if (!p_EfiDrive.EndsWith(':'))
+
+ if (!parameters.EfiDrive.EndsWith(':'))
{
- throw new ArgumentException($"Invalid EFI drive {p_EfiDrive}, it must have a colon. For example: 'Y:'.");
+ throw new ArgumentException($"Invalid EFI drive {parameters.EfiDrive}, it must have a colon. For example: 'Y:'.");
}
-
- parameters.EfiDrive = p_EfiDrive;
}
#endregion
#region DiskNumber
- if (string.IsNullOrEmpty(parameters.DiskNumber.ToString()) ||
- string.IsNullOrWhiteSpace(parameters.DiskNumber.ToString()) ||
- parameters.DiskNumber == -1)
+ if (string.IsNullOrWhiteSpace(parameters.DiskNumber.ToString()) || parameters.DiskNumber == -1)
{
- int p_DiskNumber;
+ Console.WriteLine("\n==> These are the disks available on your system:");
try
{
- Console.WriteLine("\n==> These are the disks available on your system:");
- DiskManager.ListAll();
+ SortedDictionary Disks = DiskManager.GetDisks();
+
+ foreach (KeyValuePair Disk in Disks)
+ {
+ Console.WriteLine("Disk number: {0}\nDisk model: {1}\n", Disk.Key, Disk.Value);
+ }
}
catch (Exception)
{
@@ -171,7 +163,7 @@ public static void Configure(ref Parameters parameters)
Console.Write("\n==> Please type the disk number to format (e.g. 0): ");
try
{
- p_DiskNumber = Convert.ToInt32(Console.ReadLine(), CultureInfo.CurrentCulture);
+ parameters.DiskNumber = Convert.ToInt32(Console.ReadLine(), CultureInfo.CurrentCulture);
}
catch (FormatException)
{
@@ -189,21 +181,18 @@ public static void Configure(ref Parameters parameters)
{
throw;
}
-
- parameters.DiskNumber = p_DiskNumber;
}
#endregion
#region SourceDrive
- if (string.IsNullOrEmpty(parameters.SourceDrive) ||
- string.IsNullOrWhiteSpace(parameters.SourceDrive))
+ if (string.IsNullOrWhiteSpace(parameters.SourceDrive))
{
- string? p_SourceDrive;
+ Console.Write("\n==> Specify the mount point where the source are mounted at (e.g. X:): ");
- Console.Write("\n==> Specify the mountpount where the source are mounted at (e.g. X:): ");
try
{
- p_SourceDrive = Console.ReadLine();
+ parameters.SourceDrive = Console.ReadLine() ??
+ throw new ArgumentException("A sourced drive is required.", nameof(parameters));
}
catch (IOException)
{
@@ -222,74 +211,49 @@ public static void Configure(ref Parameters parameters)
throw;
}
- ArgumentException.ThrowIfNullOrWhiteSpace(p_SourceDrive);
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.SourceDrive);
- if (p_SourceDrive.StartsWith(':'))
+ if (parameters.SourceDrive.StartsWith(':'))
{
- throw new ArgumentException(@$"Invalid source drive {p_SourceDrive}, it must have a colon at the end not at the beginning. For example: 'H:'.");
+ throw new ArgumentException(@$"Invalid source drive {parameters.SourceDrive}, it must have a colon at the end not at the beginning. For example: 'H:'.");
}
- else if (!p_SourceDrive.EndsWith(':'))
+ else if (!parameters.SourceDrive.EndsWith(':'))
{
- throw new ArgumentException($"Invalid source drive {p_SourceDrive}, it must have a colon. For example: 'H:'.");
+ throw new ArgumentException($"Invalid source drive {parameters.SourceDrive}, it must have a colon. For example: 'H:'.");
}
-
- parameters.SourceDrive = p_SourceDrive;
}
#endregion
#region ImageFilePath
- if (string.IsNullOrEmpty(parameters.ImageFilePath) ||
- string.IsNullOrWhiteSpace(parameters.ImageFilePath))
+ if (string.IsNullOrWhiteSpace(parameters.ImageFilePath))
{
- string p_ImageFilePath = DeployManager.GetImageFile(ref parameters);
+ parameters.ImageFilePath = DeployManager.GetImageFile(ref parameters);
- Console.WriteLine($"\nImage file path has been set to {p_ImageFilePath}.");
-
- parameters.ImageFilePath = p_ImageFilePath;
+ Console.WriteLine($"\nImage file path has been set to {parameters.ImageFilePath}.");
}
#endregion
#region ImageIndex
- if (string.IsNullOrEmpty(parameters.ImageIndex.ToString()) ||
- string.IsNullOrWhiteSpace(parameters.ImageIndex.ToString()) ||
- parameters.ImageIndex == -1)
+ if (parameters.ImageIndex == -1)
{
DeployManager.GetImageInfo(ref parameters);
Console.Write("\n==> Type the index number of the Windows edition you wish to install (e.g. 1): ");
- string? SelectedIndex = Console.ReadLine();
-
- if (string.IsNullOrEmpty(SelectedIndex) || string.IsNullOrWhiteSpace(SelectedIndex))
- {
- throw new ArgumentException("No Windows edition was specified.");
- }
-
- parameters.ImageIndex = Convert.ToInt32(SelectedIndex, CultureInfo.CurrentCulture);
+ parameters.ImageIndex = Convert.ToInt32(Console.ReadLine() ??
+ throw new ArgumentException("No Windows edition was specified."), CultureInfo.CurrentCulture);
}
#endregion
#region FirmwareType
- if (string.IsNullOrEmpty(parameters.FirmwareType) ||
- string.IsNullOrWhiteSpace(parameters.FirmwareType))
+ if (string.IsNullOrWhiteSpace(parameters.FirmwareType))
{
- switch (SystemInfoManager.IsEFI())
- {
- case true:
- parameters.FirmwareType = "UEFI";
- Console.WriteLine($"\nThe installer has set the firmware type to {parameters.FirmwareType}.", ConsoleColor.Yellow);
- break;
- case false:
- parameters.FirmwareType = "BIOS";
- Console.WriteLine($"\nThe installer has set the firmware type to {parameters.FirmwareType}.", ConsoleColor.Yellow);
- break;
- default:
- throw new InvalidDataException($"Invalid firmware type: {parameters.FirmwareType}");
- }
+ parameters.FirmwareType = SystemInfoManager.IsEFI() ? "UEFI" : "BIOS";
+ Console.WriteLine($"\nThe installer has set the firmware type to {parameters.FirmwareType}.", ConsoleColor.Yellow);
}
#endregion
- #region AdditionalDriversList
- if (string.IsNullOrWhiteSpace(parameters.AdditionalDriversDrive))
+ #region AdditionalDrive
+ if (string.IsNullOrWhiteSpace(parameters.AdditionalDrive))
{
Console.Write("\n=> Do you want to add additional drivers to your installation?: [Y/N]: ");
string? UserWantsExtraDrivers = Console.ReadLine()?.ToLower(CultureInfo.CurrentCulture);
@@ -317,7 +281,7 @@ public static void Configure(ref Parameters parameters)
throw new FileNotFoundException($"The directory {driversPath} does not exist");
}
- parameters.AdditionalDriversDrive = driversPath;
+ parameters.AdditionalDrive = driversPath;
break;
default:
return;
@@ -340,7 +304,7 @@ public static void Configure(ref Parameters parameters)
/// Thrown if the object contains invalid or missing values, such as: - Disk
/// number is -1. - EFI drive is null, empty, or whitespace.
[SupportedOSPlatform("windows")]
- public static void InstallWindows(ref Parameters parameters)
+ public static void Prepare(ref Parameters parameters)
{
if (parameters.DiskNumber.Equals(-1))
{
@@ -352,10 +316,11 @@ public static void InstallWindows(ref Parameters parameters)
throw new InvalidDataException("No EFI drive was specified, required for the bootloader installation.");
}
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.DestinationDrive);
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.ImageFilePath);
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.DestinationDrive, parameters.DestinationDrive);
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.EfiDrive, parameters.EfiDrive);
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.ImageFilePath, parameters.ImageFilePath);
ArgumentOutOfRangeException.ThrowIfEqual(parameters.ImageIndex, -1);
- ArgumentException.ThrowIfNullOrWhiteSpace(parameters.FirmwareType);
+ ArgumentException.ThrowIfNullOrWhiteSpace(parameters.FirmwareType, parameters.FirmwareType);
try
{
@@ -365,32 +330,35 @@ public static void InstallWindows(ref Parameters parameters)
{
Console.WriteLine($"An error occurred while formatting the disk: {ex}", ConsoleColor.Red);
}
+ }
+ public static void InstallWindows(ref Parameters parameters)
+ {
try
{
DeployManager.ApplyImage(ref parameters);
}
- catch (Exception ex)
+ catch
{
- Console.WriteLine($"An error occurred while applying the image: {ex}", ConsoleColor.Red);
+ throw;
}
try
{
DeployManager.InstallAdditionalDrivers(ref parameters);
}
- catch (Exception ex)
+ catch
{
- Console.WriteLine($"An error occurred when installing additional drivers: {ex}", ConsoleColor.Yellow);
+ throw;
}
try
{
DeployManager.InstallBootloader(ref parameters);
}
- catch (Exception ex)
+ catch
{
- Console.WriteLine($"An error occurred while installing the bootloader: {ex}", ConsoleColor.Red);
+ throw;
}
}
}
diff --git a/WindowsInstallerLib/src/ProcessManager.cs b/WindowsInstallerLib/src/ProcessManager.cs
index f4859ce..9b5264d 100644
--- a/WindowsInstallerLib/src/ProcessManager.cs
+++ b/WindowsInstallerLib/src/ProcessManager.cs
@@ -86,20 +86,31 @@ internal static int StartDiskPartProcess(int DiskNumber, string EfiDrive, string
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.CreateNoWindow = true;
+
process.Start();
Console.WriteLine($"Formatting disk {DiskNumber}, please wait...");
process.StandardInput.WriteLine($"select disk {DiskNumber}");
process.StandardInput.WriteLine("clean");
+ Console.WriteLine($"Cleaning disk {DiskNumber}...");
process.StandardInput.WriteLine("convert gpt");
+ Console.WriteLine($"Converting disk {DiskNumber} to GPT");
process.StandardInput.WriteLine("create partition efi size=100");
- process.StandardInput.WriteLine("create partition msr size=16");
+ Console.WriteLine("Creating a 100MB EFI partition...");
process.StandardInput.WriteLine("format fs=fat32 quick");
+ Console.WriteLine("Formatting EFI partition with FAT32...");
process.StandardInput.WriteLine($"assign letter {EfiDrive}");
+ Console.WriteLine($"Assigning letter {EfiDrive} to EFI partition...");
+ process.StandardInput.WriteLine("create partition msr size=16");
+ Console.WriteLine("Creating MSR partition...");
process.StandardInput.WriteLine("create partition primary");
+ Console.WriteLine($"Creating main partition...");
process.StandardInput.WriteLine("format fs=ntfs quick");
+ Console.WriteLine($"Formatting main partition with NTFS...");
process.StandardInput.WriteLine($"assign letter {DestinationDrive}");
+ Console.WriteLine($"Assigning letter {DestinationDrive} to main partition...");
process.StandardInput.WriteLine("exit");
process.WaitForExit();