diff --git a/FlybyScript/App.config b/FlybyScript/App.config index 4bfa005..d8ef5cf 100644 --- a/FlybyScript/App.config +++ b/FlybyScript/App.config @@ -1,6 +1,6 @@ - - + + - + \ No newline at end of file diff --git a/FlybyScript/Experience/FeatureBase.cs b/FlybyScript/Experience/FeatureBase.cs new file mode 100644 index 0000000..9fab011 --- /dev/null +++ b/FlybyScript/Experience/FeatureBase.cs @@ -0,0 +1,26 @@ +namespace FlybyScript +{ + public abstract class FeatureBase + { + protected readonly Logger logger; + + public Logger Logger => logger; + + protected FeatureBase(Logger logger) + { + this.logger = logger; + } + + public abstract string ID(); + + public abstract string Info(); + + public abstract bool CheckFeature(); + + public abstract bool DoFeature(); + + public abstract bool UndoFeature(); + + public abstract string GetRegistryKey(); + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/FeatureNode.cs b/FlybyScript/Experience/FeatureNode.cs new file mode 100644 index 0000000..d91a2a1 --- /dev/null +++ b/FlybyScript/Experience/FeatureNode.cs @@ -0,0 +1,15 @@ +using System.Windows.Forms; + +namespace FlybyScript +{ + internal class FeatureNode : TreeNode + { + public FeatureBase Feature { get; private set; } + + public FeatureNode(FeatureBase feature) + { + Feature = feature; + Text = Feature.ID(); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/FeaturePanel.cs b/FlybyScript/Experience/FeaturePanel.cs new file mode 100644 index 0000000..2db8e57 --- /dev/null +++ b/FlybyScript/Experience/FeaturePanel.cs @@ -0,0 +1,147 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace FlybyScript +{ + internal class FeaturePanel : Panel + { + private FeatureBase feature; + private Logger logger; + private Label statusLabel; + + public FeaturePanel(FeatureBase feature, Logger logger) + { + this.feature = feature; + this.logger = logger; + + // Create a FlowLayoutPanel + FlowLayoutPanel flowLayout = new FlowLayoutPanel + { + Dock = DockStyle.Top, + AutoSize = true, + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + AutoScroll = true + }; + + // Add Components + var descriptionLabel = CreateDescriptionLabel(); + var checkBox = CreateCheckBox(); + var linkLabel = CreateLinkLabel(); + statusLabel = CreateStatusLabel(); // Init status label + + // Event Handlers + linkLabel.Click += LinkLabel_Click; + checkBox.CheckedChanged += CheckBox_CheckedChanged; + + // Add Controls to FlowLayoutPanel + flowLayout.Controls.Add(descriptionLabel); + flowLayout.Controls.Add(checkBox); + flowLayout.Controls.Add(linkLabel); + flowLayout.Controls.Add(statusLabel); + + // Add FlowLayoutPanel to the main panel + Controls.Add(flowLayout); + } + + private Label CreateDescriptionLabel() + { + return new Label + { + Text = feature.Info(), + AutoSize = true, + Font = new Font("Segoe UI", 10, FontStyle.Regular), + ForeColor = Color.Black, + Padding = new Padding(0, 0, 0, 5) // Padding for better spacing + }; + } + + private CheckBox CreateCheckBox() + { + return new CheckBox + { + Text = feature.ID(), + AutoSize = true, + Checked = feature.CheckFeature(), + Dock = DockStyle.Top, + Font = new Font("Segoe UI", 10, FontStyle.Bold), + ForeColor = Color.Black + }; + } + + private LinkLabel CreateLinkLabel() + { + return new LinkLabel + { + Text = "Show Details", + AutoSize = true, + LinkColor = Color.Blue, + Font = new Font("Segoe UI", 10, FontStyle.Italic), + Cursor = Cursors.Hand, + Padding = new Padding(0, 0, 10, 0) // Adding some padding + }; + } + + private Label CreateStatusLabel() + { + return new Label + { + Text = feature.CheckFeature() ? "Feature Enabled" : "Feature Disabled", + AutoSize = true, + Font = new Font("Segoe UI", 10, FontStyle.Italic), + ForeColor = Color.Gray, + TextAlign = ContentAlignment.MiddleRight, + Padding = new Padding(10, 0, 0, 0) + }; + } + + private void LinkLabel_Click(object sender, EventArgs e) + { + // Copy the registry key associated with the feature to the clipboard + string registryKey = feature.GetRegistryKey(); + if (!string.IsNullOrEmpty(registryKey)) + { + Clipboard.SetText(registryKey); + MessageBox.Show($"Registry key '{registryKey}", "Copied to clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + MessageBox.Show("No registry key available for this feature.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void CheckBox_CheckedChanged(object sender, EventArgs e) + { + var checkBox = sender as CheckBox; + bool success = false; + + if (checkBox != null) + { + if (checkBox.Checked) + { + success = feature.DoFeature(); // Enable feature + if (success) + { + logger.Log($"{feature.ID()} enabled", Color.Green); + statusLabel.Text = "Feature Enabled"; // Update status label + } + } + else + { + success = feature.UndoFeature(); // Disable feature + if (success) + { + logger.Log($"{feature.ID()} disabled", Color.Red); + statusLabel.Text = "Feature Disabled"; + } + } + } + + if (!success) + { + MessageBox.Show("Failed to update feature status", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/FileExplorerAds.cs b/FlybyScript/Experience/FileExplorerAds.cs new file mode 100644 index 0000000..36a9833 --- /dev/null +++ b/FlybyScript/Experience/FileExplorerAds.cs @@ -0,0 +1,68 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class FileExplorerAds : FeatureBase + { + public FileExplorerAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"; + private const string valueName = "ShowSyncProviderNotifications"; + private const int desiredValue = 0; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override string ID() + { + return "Disable File Explorer Ads"; + } + + public override string Info() + { + return "This feature will disable ads in File Explorer."; + } + + public override bool CheckFeature() + { + return (Utils.IntEquals(keyName, valueName, desiredValue)); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/FindMyDevice.cs b/FlybyScript/Experience/FindMyDevice.cs new file mode 100644 index 0000000..0cae81f --- /dev/null +++ b/FlybyScript/Experience/FindMyDevice.cs @@ -0,0 +1,71 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Privacy +{ + internal class FindMyDevice : FeatureBase + { + public FindMyDevice(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location"; + private const string valueName = "Value"; + private const string desiredValue = @"Allow"; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override string ID() + { + return "Disable Find my device"; + } + + public override string Info() + { + return "This feature will disable find my device."; + } + + public override bool CheckFeature() + { + return !( + Utils.StringEquals(keyName, valueName, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, "Deny", RegistryValueKind.String); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, desiredValue, RegistryValueKind.String); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/FinishSetupAds.cs b/FlybyScript/Experience/FinishSetupAds.cs new file mode 100644 index 0000000..7430202 --- /dev/null +++ b/FlybyScript/Experience/FinishSetupAds.cs @@ -0,0 +1,64 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + public class FinishSetupAds : FeatureBase + { + public FinishSetupAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement"; + private const string valueName = "ScoobeSystemSettingEnabled"; + private const int desiredValue = 0; + + public override string ID() => "Disable Finish Setup Ads"; + + public override string Info() => "This feature will disable the \"Lets finish setting up your device\" and other advertising."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return Utils.IntEquals(keyName, valueName, 0); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/LockScreenAds.cs b/FlybyScript/Experience/LockScreenAds.cs new file mode 100644 index 0000000..925ea86 --- /dev/null +++ b/FlybyScript/Experience/LockScreenAds.cs @@ -0,0 +1,69 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class LockScreenAds : FeatureBase + { + public LockScreenAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"; + private const string valueName = "RotatingLockScreenOverlayEnabled"; + private const string valueName2 = "SubscribedContent-338387Enabled"; + private const int desiredValue = 0; + + public override string ID() => "Disable Lock Screen Tips and Ads"; + + public override string Info() => "This feature will disable tips and ads on the lock screen."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return (Utils.IntEquals(keyName, valueName, desiredValue) && + Utils.IntEquals(keyName, valueName2, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName2, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName2, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/PersonalizedAds.cs b/FlybyScript/Experience/PersonalizedAds.cs new file mode 100644 index 0000000..3c5c25b --- /dev/null +++ b/FlybyScript/Experience/PersonalizedAds.cs @@ -0,0 +1,64 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + public class PersonalizedAds : FeatureBase + { + public PersonalizedAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo"; + private const string valueName = "Enabled"; + private const int desiredValue = 0; + + public override string ID() => "Disable Personalized Ads"; + + public override string Info() => "This feature will disable personalized ads."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return Utils.IntEquals(keyName, valueName, 0); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/PrivacyExperience.cs b/FlybyScript/Experience/PrivacyExperience.cs new file mode 100644 index 0000000..7134902 --- /dev/null +++ b/FlybyScript/Experience/PrivacyExperience.cs @@ -0,0 +1,64 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Privacy +{ + public class PrivacyExperience : FeatureBase + { + public PrivacyExperience(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OOBE"; + private const string valueName = "DisablePrivacyExperience"; + private const int desiredValue = 0; + + public override string ID() => "Disable Privacy Settings Experience at sign-in"; + + public override string Info() => "This feature will disable Privacy Settings Experience at sign-in."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return !Utils.IntEquals(keyName, valueName, desiredValue); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/SettingsAds.cs b/FlybyScript/Experience/SettingsAds.cs new file mode 100644 index 0000000..ff96abc --- /dev/null +++ b/FlybyScript/Experience/SettingsAds.cs @@ -0,0 +1,74 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class SettingsAds : FeatureBase + { + public SettingsAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"; + private const string valueName = "SubscribedContent-338393Enabled"; + private const string valueName2 = "SubscribedContent-353694Enabled"; + private const string valueName3 = "SubscribedContent-353696Enabled"; + + private const int desiredValue = 0; + + public override string ID() => "Disable Settings Ads"; + + public override string Info() => "This feature will disable ads in settings."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} + {valueName2} + {valueName3} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return (Utils.IntEquals(keyName, valueName, desiredValue) && + Utils.IntEquals(keyName, valueName2, desiredValue) && + Utils.IntEquals(keyName, valueName3, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName2, 0, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName3, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName2, 1, Microsoft.Win32.RegistryValueKind.DWord); + Registry.SetValue(keyName, valueName3, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/StartmenuAds.cs b/FlybyScript/Experience/StartmenuAds.cs new file mode 100644 index 0000000..9352449 --- /dev/null +++ b/FlybyScript/Experience/StartmenuAds.cs @@ -0,0 +1,70 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class StartmenuAds : FeatureBase + { + public StartmenuAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"; + private const string valueName = "Start_IrisRecommendations"; + private const int desiredValue = 0; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override string ID() + { + return "Disable Start menu Ads"; + } + + public override string Info() + { + return "This feature will disable ads in the start menu."; + } + + public override bool CheckFeature() + { + return ( + Utils.IntEquals(keyName, valueName, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/TailoredExperiences.cs b/FlybyScript/Experience/TailoredExperiences.cs new file mode 100644 index 0000000..d35b0e5 --- /dev/null +++ b/FlybyScript/Experience/TailoredExperiences.cs @@ -0,0 +1,70 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class TailoredExperiences : FeatureBase + { + public TailoredExperiences(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Privacy"; + private const string valueName = "TailoredExperiencesWithDiagnosticDataEnabled"; + private const int desiredValue = 0; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override string ID() + { + return "Disable Tailored experiences"; + } + + public override string Info() + { + return "Tailored Experiences allows Microsoft to get information from you to deliver personalized tips, ads, and recommendations. Many people would call this telemetry, or even spying."; + } + + public override bool CheckFeature() + { + return ( + Utils.IntEquals(keyName, valueName, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord); + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/Telemetry.cs b/FlybyScript/Experience/Telemetry.cs new file mode 100644 index 0000000..ca88637 --- /dev/null +++ b/FlybyScript/Experience/Telemetry.cs @@ -0,0 +1,69 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Privacy +{ + public class Telemetry : FeatureBase + { + public Telemetry(Logger logger) : base(logger) + { + } + + private const string dataCollection = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection"; + private const string diagTrack = @"HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\DiagTrack"; + + public override string ID() => "Turn off Telemetry data collection"; + + public override string Info() => "This feature will turn off telemetry data collection and prevent the data from being sent to Microsoft."; + + public override string GetRegistryKey() + { + return $"{dataCollection} | {diagTrack}"; + } + + public override bool CheckFeature() + { + return ( + Utils.IntEquals(dataCollection, "AllowTelemetry", 0) && + Utils.IntEquals(diagTrack, "Start", 2) + + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(dataCollection, "AllowTelemetry", 0, RegistryValueKind.DWord); + Registry.SetValue(diagTrack, "Start", 2, RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(dataCollection, "AllowTelemetry", 1, RegistryValueKind.DWord); + Registry.SetValue(diagTrack, "Start", 4, RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/TipsAndSuggestions.cs b/FlybyScript/Experience/TipsAndSuggestions.cs new file mode 100644 index 0000000..2c05d9d --- /dev/null +++ b/FlybyScript/Experience/TipsAndSuggestions.cs @@ -0,0 +1,65 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + internal class TipsAndSuggestions : FeatureBase + { + public TipsAndSuggestions(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"; + private const string valueName = "SubscribedContent-338389Enabled"; + private const int desiredValue = 0; + + public override string ID() => "Disable General Tips and Ads"; + + public override string Info() => "This feature will disable general tips and ads."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return (Utils.IntEquals(keyName, valueName, desiredValue) + ); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/Experience/WelcomeExperienceAds.cs b/FlybyScript/Experience/WelcomeExperienceAds.cs new file mode 100644 index 0000000..a01a2eb --- /dev/null +++ b/FlybyScript/Experience/WelcomeExperienceAds.cs @@ -0,0 +1,64 @@ +using FlybyScript; +using Microsoft.Win32; +using System; +using System.Drawing; + +namespace Settings.Ads +{ + public class WelcomeExperienceAds : FeatureBase + { + public WelcomeExperienceAds(Logger logger) : base(logger) + { + } + + private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"; + private const string valueName = "SubscribedContent-310093Enabled"; + private const int desiredValue = 0; + + public override string ID() => "Disable Welcome Experience Ads"; + + public override string Info() => "This feature will disable ads in the welcome experience."; + + public override string GetRegistryKey() + { + return $"{keyName} | Value: {valueName} | Desired Value: {desiredValue}"; + } + + public override bool CheckFeature() + { + return Utils.IntEquals(keyName, valueName, 0); + } + + public override bool DoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + + public override bool UndoFeature() + { + try + { + Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord); + + return true; + } + catch (Exception ex) + { + logger.Log("Code red in " + ex.Message, Color.Red); + } + + return false; + } + } +} \ No newline at end of file diff --git a/FlybyScript/FlybyScript.csproj b/FlybyScript/FlybyScript.csproj index 7b2d6a8..ce0e4b0 100644 --- a/FlybyScript/FlybyScript.csproj +++ b/FlybyScript/FlybyScript.csproj @@ -7,7 +7,7 @@ {66DDC36A-9095-4053-941C-8829D44F5F20} WinExe FlybyScript - FlybyScript + Flyby11 v4.8 512 true @@ -56,6 +56,22 @@ + + Component + + + + + + + + + + + + + + @@ -69,12 +85,21 @@ + + + UserControl ExperienceView.cs + + UserControl + + + MediaView.cs + MainForm.cs Designer @@ -92,6 +117,9 @@ ExperienceView.cs + + MediaView.cs + diff --git a/FlybyScript/Helper/Logger.cs b/FlybyScript/Helper/Logger.cs index d340ab5..46e945b 100644 --- a/FlybyScript/Helper/Logger.cs +++ b/FlybyScript/Helper/Logger.cs @@ -28,9 +28,7 @@ namespace FlybyScript private void LogMessage(string message, Color color) { rtbDescription.SelectionColor = color; - - rtbDescription.AppendText($"{message}\n"); - + rtbDescription.AppendText($"{DateTime.Now:HH:mm:ss} - {message}\n"); rtbDescription.ScrollToCaret(); } } diff --git a/FlybyScript/Helper/Utils.cs b/FlybyScript/Helper/Utils.cs new file mode 100644 index 0000000..53455cd --- /dev/null +++ b/FlybyScript/Helper/Utils.cs @@ -0,0 +1,67 @@ +using Microsoft.Win32; +using System; +using System.Diagnostics; +using System.Windows.Forms; + +namespace FlybyScript +{ + internal class Utils + { + // Check registry int equal + public static bool IntEquals(string keyName, string valueName, int expectedValue) + { + try + { + var value = Registry.GetValue(keyName, valueName, null); + return (value != null && (int)value == expectedValue); + } + catch (Exception ex) + + { + MessageBox.Show(keyName, ex.Message, MessageBoxButtons.OK); + return false; + } + } + + // Check registry strings equal + public static bool StringEquals(string keyName, string valueName, string expectedValue) + { + try + { + var value = Registry.GetValue(keyName, valueName, null); + + return (value != null && (string)value == expectedValue); + } + catch (Exception ex) + { + MessageBox.Show(keyName, ex.Message, MessageBoxButtons.OK); + return false; + } + } + + public static bool KeyExists(string keyPath) + { + return Registry.GetValue(keyPath, null, null) != null; + } + + public static bool IsProcessRunning(string processName) + { + Process[] processes = Process.GetProcessesByName(processName); + return processes.Length > 0; + } + + // Launch Urls in richText control + public static void LaunchUri(string url) + { + if (IsHttpURL(url)) Process.Start(url); + } + + // Check Urls in in richText control + public static bool IsHttpURL(string url) + { + return + ((!string.IsNullOrWhiteSpace(url)) && + (url.ToLower().StartsWith("http"))); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Helper/Views.cs b/FlybyScript/Helper/Views.cs index e4bfdb1..2e38431 100644 --- a/FlybyScript/Helper/Views.cs +++ b/FlybyScript/Helper/Views.cs @@ -1,5 +1,4 @@ -using System.Linq; -using System.Windows.Forms; +using System.Windows.Forms; namespace Views { diff --git a/FlybyScript/MainForm.Designer.cs b/FlybyScript/MainForm.Designer.cs index d874398..25c4c51 100644 --- a/FlybyScript/MainForm.Designer.cs +++ b/FlybyScript/MainForm.Designer.cs @@ -34,10 +34,11 @@ this.btnTogglePatch = new System.Windows.Forms.Button(); this.linkGitHub = new System.Windows.Forms.LinkLabel(); this.btnMountRun = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); + this.lblHeader = new System.Windows.Forms.Label(); this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.linkLabel2 = new System.Windows.Forms.LinkLabel(); this.panelMain = new System.Windows.Forms.Panel(); + this.checkInstallationMedia = new System.Windows.Forms.CheckBox(); this.linkChangeExperience = new System.Windows.Forms.LinkLabel(); this.panelForm = new System.Windows.Forms.Panel(); this.panelMain.SuspendLayout(); @@ -46,12 +47,13 @@ // // treeSettings // - this.treeSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.treeSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.treeSettings.BackColor = System.Drawing.Color.White; this.treeSettings.BorderStyle = System.Windows.Forms.BorderStyle.None; this.treeSettings.CheckBoxes = true; - this.treeSettings.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.treeSettings.Font = new System.Drawing.Font("Segoe UI Variable Text Light", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.treeSettings.ForeColor = System.Drawing.Color.Black; this.treeSettings.FullRowSelect = true; this.treeSettings.Indent = 20; @@ -66,7 +68,7 @@ this.treeSettings.TabIndex = 200; this.treeSettings.TabStop = false; this.treeSettings.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeSettings_AfterCheck); - this.treeSettings.MouseMove += new System.Windows.Forms.MouseEventHandler(this.treeSettings_MouseMove); + this.treeSettings.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeSettings_NodeMouseClick); // // rtbDescription // @@ -93,26 +95,27 @@ this.btnTogglePatch.FlatAppearance.BorderSize = 2; this.btnTogglePatch.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); this.btnTogglePatch.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnTogglePatch.Font = new System.Drawing.Font("Segoe UI Variable Small", 11F); - this.btnTogglePatch.Location = new System.Drawing.Point(629, 497); + this.btnTogglePatch.Font = new System.Drawing.Font("Segoe UI Variable Small", 10F); + this.btnTogglePatch.Location = new System.Drawing.Point(629, 484); this.btnTogglePatch.Name = "btnTogglePatch"; this.btnTogglePatch.Size = new System.Drawing.Size(222, 40); this.btnTogglePatch.TabIndex = 201; this.btnTogglePatch.TabStop = false; - this.btnTogglePatch.Text = "Patch"; + this.btnTogglePatch.Text = "Start"; this.btnTogglePatch.UseCompatibleTextRendering = true; this.btnTogglePatch.UseVisualStyleBackColor = false; this.btnTogglePatch.Click += new System.EventHandler(this.btnTogglePatch_Click); // // linkGitHub // - this.linkGitHub.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkGitHub.ActiveLinkColor = System.Drawing.Color.RoyalBlue; this.linkGitHub.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.linkGitHub.AutoEllipsis = true; + this.linkGitHub.AutoSize = true; this.linkGitHub.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); this.linkGitHub.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; this.linkGitHub.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(65)))), ((int)(((byte)(17))))); - this.linkGitHub.Location = new System.Drawing.Point(169, 567); + this.linkGitHub.Location = new System.Drawing.Point(167, 558); this.linkGitHub.Name = "linkGitHub"; this.linkGitHub.Size = new System.Drawing.Size(45, 16); this.linkGitHub.TabIndex = 202; @@ -130,8 +133,8 @@ this.btnMountRun.FlatAppearance.BorderSize = 2; this.btnMountRun.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); this.btnMountRun.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnMountRun.Font = new System.Drawing.Font("Segoe UI Variable Small", 11F); - this.btnMountRun.Location = new System.Drawing.Point(403, 497); + this.btnMountRun.Font = new System.Drawing.Font("Segoe UI Variable Small", 10F); + this.btnMountRun.Location = new System.Drawing.Point(403, 484); this.btnMountRun.Name = "btnMountRun"; this.btnMountRun.Size = new System.Drawing.Size(220, 40); this.btnMountRun.TabIndex = 203; @@ -140,55 +143,58 @@ this.btnMountRun.UseVisualStyleBackColor = false; this.btnMountRun.Click += new System.EventHandler(this.btnMountRun_Click); // - // label1 + // lblHeader // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.lblHeader.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.label1.AutoEllipsis = true; - this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 21.25F); - this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); - this.label1.Location = new System.Drawing.Point(30, 38); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(780, 82); - this.label1.TabIndex = 205; - this.label1.Text = "Utilize FlybyScript to Bypass Windows 11 Hardware Restrictions and Install on Uns" + - "upported Devices"; + this.lblHeader.AutoEllipsis = true; + this.lblHeader.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 21.25F); + this.lblHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.lblHeader.Location = new System.Drawing.Point(30, 38); + this.lblHeader.Name = "lblHeader"; + this.lblHeader.Size = new System.Drawing.Size(780, 82); + this.lblHeader.TabIndex = 205; + this.lblHeader.Text = "Use FlybyScript to bypass Windows 11 restrictions and install on unsupported devi" + + "ces"; // // linkLabel1 // - this.linkLabel1.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkLabel1.ActiveLinkColor = System.Drawing.Color.RoyalBlue; this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.linkLabel1.AutoEllipsis = true; + this.linkLabel1.AutoSize = true; this.linkLabel1.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); this.linkLabel1.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; - this.linkLabel1.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(164)))), ((int)(((byte)(239))))); - this.linkLabel1.Location = new System.Drawing.Point(27, 567); + this.linkLabel1.LinkColor = System.Drawing.Color.Gray; + this.linkLabel1.Location = new System.Drawing.Point(31, 558); this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(122, 16); + this.linkLabel1.Size = new System.Drawing.Size(119, 16); this.linkLabel1.TabIndex = 206; this.linkLabel1.TabStop = true; this.linkLabel1.Text = "A Belim app creation"; // // linkLabel2 // - this.linkLabel2.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkLabel2.ActiveLinkColor = System.Drawing.Color.RoyalBlue; this.linkLabel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.linkLabel2.AutoEllipsis = true; + this.linkLabel2.AutoSize = true; this.linkLabel2.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); this.linkLabel2.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; this.linkLabel2.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(186)))), ((int)(((byte)(0))))); - this.linkLabel2.Location = new System.Drawing.Point(235, 567); + this.linkLabel2.Location = new System.Drawing.Point(233, 558); this.linkLabel2.Name = "linkLabel2"; - this.linkLabel2.Size = new System.Drawing.Size(54, 16); + this.linkLabel2.Size = new System.Drawing.Size(44, 16); this.linkLabel2.TabIndex = 208; this.linkLabel2.TabStop = true; - this.linkLabel2.Text = "0.11.31"; + this.linkLabel2.Text = "0.13.81"; // // panelMain // + this.panelMain.Controls.Add(this.checkInstallationMedia); this.panelMain.Controls.Add(this.linkLabel2); this.panelMain.Controls.Add(this.linkChangeExperience); - this.panelMain.Controls.Add(this.label1); + this.panelMain.Controls.Add(this.lblHeader); this.panelMain.Controls.Add(this.linkLabel1); this.panelMain.Controls.Add(this.rtbDescription); this.panelMain.Controls.Add(this.treeSettings); @@ -201,9 +207,23 @@ this.panelMain.Size = new System.Drawing.Size(943, 592); this.panelMain.TabIndex = 209; // + // checkInstallationMedia + // + this.checkInstallationMedia.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkInstallationMedia.AutoSize = true; + this.checkInstallationMedia.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.checkInstallationMedia.Location = new System.Drawing.Point(34, 528); + this.checkInstallationMedia.Name = "checkInstallationMedia"; + this.checkInstallationMedia.Size = new System.Drawing.Size(245, 17); + this.checkInstallationMedia.TabIndex = 209; + this.checkInstallationMedia.Text = "I want to create Windows 11 installation media"; + this.checkInstallationMedia.UseVisualStyleBackColor = true; + this.checkInstallationMedia.CheckedChanged += new System.EventHandler(this.checkInstallationMedia_CheckedChanged); + // // linkChangeExperience // - this.linkChangeExperience.ActiveLinkColor = System.Drawing.Color.Fuchsia; + this.linkChangeExperience.ActiveLinkColor = System.Drawing.Color.RoyalBlue; + this.linkChangeExperience.AutoEllipsis = true; this.linkChangeExperience.AutoSize = true; this.linkChangeExperience.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.linkChangeExperience.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; @@ -211,10 +231,11 @@ this.linkChangeExperience.Location = new System.Drawing.Point(33, 139); this.linkChangeExperience.Name = "linkChangeExperience"; this.linkChangeExperience.Size = new System.Drawing.Size(209, 16); - this.linkChangeExperience.TabIndex = 10; + this.linkChangeExperience.TabIndex = 1; this.linkChangeExperience.TabStop = true; this.linkChangeExperience.Text = "Change how you experience Windows"; this.linkChangeExperience.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkChangeExperience_LinkClicked); + this.linkChangeExperience.Paint += new System.Windows.Forms.PaintEventHandler(this.linkChangeExperience_Paint); // // panelForm // @@ -250,12 +271,13 @@ private System.Windows.Forms.Button btnTogglePatch; private System.Windows.Forms.LinkLabel linkGitHub; private System.Windows.Forms.Button btnMountRun; - private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lblHeader; private System.Windows.Forms.LinkLabel linkLabel1; private System.Windows.Forms.LinkLabel linkLabel2; private System.Windows.Forms.Panel panelMain; private System.Windows.Forms.LinkLabel linkChangeExperience; private System.Windows.Forms.Panel panelForm; + private System.Windows.Forms.CheckBox checkInstallationMedia; } } diff --git a/FlybyScript/MainForm.cs b/FlybyScript/MainForm.cs index 50cd626..75e4aa1 100644 --- a/FlybyScript/MainForm.cs +++ b/FlybyScript/MainForm.cs @@ -24,6 +24,7 @@ namespace FlybyScript // Set the default view to the main panel SwitchView.DefaultView = panelMain; + } private async void MainForm_Load(object sender, EventArgs e) @@ -160,7 +161,7 @@ namespace FlybyScript btnTogglePatch.Enabled = true; } - private void treeSettings_MouseMove(object sender, MouseEventArgs e) + private void treeSettings_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { TreeNode node = treeSettings.GetNodeAt(e.Location); @@ -169,7 +170,7 @@ namespace FlybyScript // Check if the node's Tag is the native "Method1" if (node.Tag?.ToString() == "Method1") { - rtbDescription.Text = "Inplace Upgrade via Server Setup\nThis method leverages the Windows Server variant of the Windows setup, " + + rtbDescription.Text = "(Current release: Windows 11 2024 Update l Version 24H2)\nThis method leverages the Windows Server variant of the Windows setup, " + "which skips most hardware compatibility checks. It allows Windows 11 to be installed on unsupported PCs, " + "bypassing the usual system requirements. Importantly, while the setup runs in server mode, " + "it installs the standard Windows 11 (not the server version).\n\nHow it works:\n1. " + @@ -210,10 +211,25 @@ namespace FlybyScript await patcher.RunSetupFromMountedISO(); } + private void linkChangeExperience_Paint(object sender, PaintEventArgs e) + { + // Linkoption gains focus so trigger a vivid focus rectangle + ControlPaint.DrawFocusRectangle(e.Graphics, linkChangeExperience.ClientRectangle); + } + private void linkChangeExperience_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { - ExperienceView exprienceView = new ExperienceView(); - SwitchView.SetView(exprienceView, panelForm); + ExperienceView experienceView = new ExperienceView(); + SwitchView.SetView(experienceView, panelForm); } + + private void checkInstallationMedia_CheckedChanged(object sender, EventArgs e) + { + checkInstallationMedia.Checked = false; + MediaView installMediaView = new MediaView(); + SwitchView.SetView(installMediaView, panelForm); + } + + } } \ No newline at end of file diff --git a/FlybyScript/Patcher/NativePatcher.cs b/FlybyScript/Patcher/NativePatcher.cs index fd876a7..3b271b2 100644 --- a/FlybyScript/Patcher/NativePatcher.cs +++ b/FlybyScript/Patcher/NativePatcher.cs @@ -77,17 +77,10 @@ namespace FlybyScript { try { - OpenFileDialog openFileDialog = new OpenFileDialog - { - Title = "Select Windows 24H2 ISO File", - Filter = "ISO Files (*.iso)|*.iso|All Files (*.*)|*.*", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer) - }; + string isoFilePath = SelectISOFile(); - if (openFileDialog.ShowDialog() == DialogResult.OK) + if (!string.IsNullOrEmpty(isoFilePath)) { - string isoFilePath = openFileDialog.FileName; - MessageBox.Show($"Selected ISO file: {isoFilePath}. Now mounting the ISO.", "ISO Selected", MessageBoxButtons.OK, MessageBoxIcon.Information); _logger.Log($"Mounting ISO: {isoFilePath}...", System.Drawing.Color.Blue); @@ -124,44 +117,55 @@ namespace FlybyScript private async Task RunSetup(string mountedDriveLetter) { + if (string.IsNullOrEmpty(mountedDriveLetter)) + { + _logger.Log("No mounted drive found. Exiting.", System.Drawing.Color.Crimson); + return; + } + + // Log the drive letter and build the sources folder path + string sourcesFolderPath = Path.Combine(mountedDriveLetter, "sources"); + _logger.Log($"Mounted drive letter: {mountedDriveLetter}", System.Drawing.Color.Gray); + _logger.Log($"Checking Sources folder at: {sourcesFolderPath}", System.Drawing.Color.Gray); + + // Check if Sources folder exists + if (!Directory.Exists(sourcesFolderPath)) + { + _logger.Log($"Sources folder not found at {sourcesFolderPath}.", System.Drawing.Color.Crimson); + return; + } + + await LaunchSetupFromSourcesFolder(sourcesFolderPath); + } + + private async Task LaunchSetupFromSourcesFolder(string sourcesFolderPath) + { + var processInfo = new ProcessStartInfo + { + FileName = Path.Combine(sourcesFolderPath, "setupprep.exe"), + Arguments = "/product server", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + try { - // Check if the mounted drive is available - if (string.IsNullOrEmpty(mountedDriveLetter)) + using (var process = Process.Start(processInfo)) { - _logger.Log("No mounted drive found. Exiting.", System.Drawing.Color.Crimson); - return; + // Capture output and wait for exit + string output = await process.StandardOutput.ReadToEndAsync(); + string error = await process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + + // Log output and errors if any + if (!string.IsNullOrEmpty(output)) _logger.Log($"Output: {output}", System.Drawing.Color.Gray); + if (!string.IsNullOrEmpty(error)) _logger.Log($"Error: {error}", System.Drawing.Color.Crimson); } - // Log the drive letter - _logger.Log($"Mounted drive letter: {mountedDriveLetter}", System.Drawing.Color.Gray); - - // Build the path to the Sources folder - string sourcesFolderPath = Path.Combine(mountedDriveLetter, "sources"); - - // Path correct? - _logger.Log($"Checking Sources folder at: {sourcesFolderPath}", System.Drawing.Color.Gray); - - // Check if Sources folder exists - if (Directory.Exists(sourcesFolderPath)) - { - _logger.Log($"Found Sources folder at {sourcesFolderPath}. Opening CMD and running setupprep.exe.", System.Drawing.Color.Green); - - // Prepare the CMD command to open cmd, then run 'setupprep.exe /product server' - string cmdCommand = $"/C \"cd /d {sourcesFolderPath} && start cmd /k setupprep.exe /product server\""; - - // Execute the CMD command, which will open a new CMD window - ProcessStart(cmdCommand); - - MessageBox.Show("Follow the Windows Server Setup window now. You can close the command window and the Flyby11 app.", - "Information", - MessageBoxButtons.OK, - MessageBoxIcon.Information); - } - else - { - _logger.Log($"Sources folder not found at {sourcesFolderPath}.", System.Drawing.Color.Crimson); - } + MessageBox.Show("Follow the Windows Server Setup window now. You can close this message box and the FlybyScript.", + "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { @@ -169,7 +173,6 @@ namespace FlybyScript } } - // btnMountRunSetup_Click: Run setup.exe from a mounted ISO on the fly public async Task RunSetupFromMountedISO() { // Choose an ISO file @@ -178,6 +181,8 @@ namespace FlybyScript try { + _logger.Log($"Please wait...", System.Drawing.Color.Crimson); + // Mount the selected ISO await ExecutePowerShellCommand($"Mount-DiskImage -ImagePath \"{isoFilePath}\""); @@ -185,33 +190,26 @@ namespace FlybyScript string mountedDriveLetter = await GetMountedDriveLetter(); if (string.IsNullOrEmpty(mountedDriveLetter)) { - _logger.Log("Failed to get mounted drive letter.", Color.Crimson); + _logger.Log("Failed to get mounted drive letter.", System.Drawing.Color.Crimson); return; } - // Check if setup.exe exists and start it - string setupPath = Path.Combine(mountedDriveLetter, "setup.exe"); - if (File.Exists(setupPath)) + _logger.Log($"Mounted drive letter: {mountedDriveLetter}", System.Drawing.Color.Gray); + + // Define Sources folder path and check if it exists + string sourcesFolderPath = Path.Combine(mountedDriveLetter, "sources"); + if (Directory.Exists(sourcesFolderPath)) { - _logger.Log($"Found setup.exe at {setupPath}. Launching setup.", Color.Green); - - Process.Start(new ProcessStartInfo - { - FileName = setupPath, - UseShellExecute = true, - CreateNoWindow = false - }); - - MessageBox.Show("Windows Setup has started. Follow the on-screen instructions.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + await LaunchSetupFromSourcesFolder(sourcesFolderPath); } else { - _logger.Log($"setup.exe not found at {setupPath}.", Color.Crimson); + _logger.Log($"Sources folder not found at {sourcesFolderPath}.", System.Drawing.Color.Crimson); } } catch (Exception ex) { - _logger.Log($"Error running setup.exe: {ex.Message}", Color.Crimson); + _logger.Log($"Error mounting ISO or launching setup: {ex.Message}", System.Drawing.Color.Crimson); } } @@ -328,6 +326,7 @@ namespace FlybyScript return null; } } + private string SelectISOFile() { using (var openFileDialog = new OpenFileDialog @@ -340,6 +339,5 @@ namespace FlybyScript return openFileDialog.ShowDialog() == DialogResult.OK ? openFileDialog.FileName : null; } } - } } \ No newline at end of file diff --git a/FlybyScript/Patcher/PSPatcher.cs b/FlybyScript/Patcher/PSPatcher.cs index 19cd32e..9587f79 100644 --- a/FlybyScript/Patcher/PSPatcher.cs +++ b/FlybyScript/Patcher/PSPatcher.cs @@ -1,10 +1,10 @@ -using System; +using FlybyScript; +using System; using System.Diagnostics; using System.IO; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using FlybyScript; public class PSPatcher { diff --git a/FlybyScript/Properties/AssemblyInfo.cs b/FlybyScript/Properties/AssemblyInfo.cs index 9cd86d4..93e86be 100644 --- a/FlybyScript/Properties/AssemblyInfo.cs +++ b/FlybyScript/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // Allgemeine Informationen über eine Assembly werden über die folgenden @@ -29,5 +28,5 @@ using System.Runtime.InteropServices; // Buildnummer // Revision // -[assembly: AssemblyVersion("0.11.31")] -[assembly: AssemblyFileVersion("0.11.31")] +[assembly: AssemblyVersion("0.13.81")] +[assembly: AssemblyFileVersion("0.13.81")] \ No newline at end of file diff --git a/FlybyScript/USBManagement.cs b/FlybyScript/USBManagement.cs new file mode 100644 index 0000000..e53041a --- /dev/null +++ b/FlybyScript/USBManagement.cs @@ -0,0 +1,441 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace FlybyScript +{ + public class USBManagement + { + private readonly Logger _logger; + private ProgressBar _progressBar; + + public Action UpdateLabelStatus; + private int currentStep = 0; + + private static readonly HttpClient httpClient = new HttpClient(); + + public USBManagement(Logger logger, Action updateLabelStatus, ProgressBar progressBar) + { + _logger = logger; + _progressBar = progressBar; + UpdateLabelStatus = updateLabelStatus; // Set the delegate to update UI + } + + private string[] steps = new[] + { + "Format and Boot USB Drive", + "Mount ISO", + "Copy ISO to USB", + "Split Install.wim", + "Finalize Installation Media (Install.wim)" + }; + + /// + /// Updates the LabelStatus with the current step + /// + public void UpdateStatusLabel() + { + currentStep++; + if (currentStep <= steps.Length) + { + string statusText = $"{currentStep}/{steps.Length} - {steps[currentStep - 1]}"; + + // Call the delegate to update the label in the user control + UpdateLabelStatus?.Invoke(statusText); + + // Log to the logger as well + _logger.Log($"Step {currentStep}: {steps[currentStep - 1]} started.", Color.Blue); + } + } + + /// + /// Updates the progress bar with the specified value + /// + private void UpdateProgress(int value) + { + if (_progressBar.InvokeRequired) + { + _progressBar.Invoke(new Action(() => _progressBar.Value = value)); + } + else + { + _progressBar.Value = value; + } + } + + /// + /// Formats the USB drive using DiskPart + /// + /// Diskpart Device ID + /// + public async Task FormatDriveAsync(string diskNumber) + { + await Task.Run(() => + { + try + { + ProcessStartInfo processInfo = new ProcessStartInfo + { + FileName = "diskpart.exe", + RedirectStandardInput = true, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using (Process process = Process.Start(processInfo)) + { + using (StreamWriter writer = process.StandardInput) + { + if (writer.BaseStream.CanWrite) + { + // Step 1: Format and Boot USB Drive + UpdateStatusLabel(); // Updates to 1/5 - Format and Boot USB Drive + + // Send commands to DiskPart + writer.WriteLine($"select disk {diskNumber}"); // Select the disk based on user input + + UpdateProgress(10); // Update progress + writer.WriteLine("clean"); // Clean the disk + + writer.WriteLine("convert mbr"); // Convert to MBR + + UpdateProgress(20); + writer.WriteLine("create partition primary"); // Create a new partition + writer.WriteLine("select partition 1"); // Select the new partition + writer.WriteLine("active"); // Set the new partition active + + UpdateProgress(60); + writer.WriteLine("format fs=fat32 quick label=\"FlybyWin11\""); // Quick format to FAT32 + + // writer.WriteLine("assign letter=W"); // Assign drive letter + writer.WriteLine("exit"); // Exit DiskPart + UpdateProgress(100); // Final progress + } + } + + string output = process.StandardOutput.ReadToEnd(); // Get the output from DiskPart + process.WaitForExit(); // Wait for the process to exit + _logger.Log($"Formatting completed: {output}", Color.Black); + } + } + catch (Exception ex) + { + _logger.Log($"Error formatting drive: {ex.Message}", Color.Red); + } + }); + } + + /// + /// Copies the contents of the specified ISO file to the USB drive using Robocopy. + /// + /// The drive letter of the USB drive. + /// The path to the ISO file. + public async Task CopyISOAsync(string usbDrive, string isoPath) + { + try + { + // Step 1: Mount the ISO using PowerShell + UpdateStatusLabel(); // Updates to "2/5 - Mount ISO" + string mountCommand = $"Mount-DiskImage -ImagePath \"{isoPath}\""; + ProcessStartInfo mountInfo = new ProcessStartInfo("powershell", mountCommand) + { + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using (Process mountProcess = Process.Start(mountInfo)) + { + string output = await mountProcess.StandardOutput.ReadToEndAsync(); + await mountProcess.WaitForExitAsync(); // Wait for the process to complete + _logger.Log($"ISO mounted: {output}", Color.Black); + } + + // Step 2: Get the drive letter of the mounted ISO + string isoDriveLetter = await GetMountedDriveLetterAsync(); // Get the drive letter of the mounted ISO + if (string.IsNullOrEmpty(isoDriveLetter)) + { + _logger.Log("Failed to get the mounted ISO drive letter.", Color.Red); + return; // Exit if we cant find the drive letter + } + + _logger.Log($"Mounted ISO drive letter: {isoDriveLetter}", Color.Black); + _logger.Log($"USB drive letter: {usbDrive}", Color.Black); + + // Step 3: Prepare the Robocopy command to copy everything except install.wim + string robocopyCommand = $"robocopy {isoDriveLetter.TrimEnd('\\')} {usbDrive.TrimEnd('\\')} /MIR /XF \"install.wim\""; + + // Step 4: Execute the Robocopy command + ProcessStartInfo robocopyInfo = new ProcessStartInfo("cmd.exe", $"/C {robocopyCommand}") + { + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + // Step 3: Copy ISO to USB + UpdateStatusLabel(); // Updates to "3/5 - Copy ISO to USB" + using (Process robocopyProcess = Process.Start(robocopyInfo)) + { + robocopyProcess.OutputDataReceived += (s, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + _logger.Log(e.Data, Color.Black); + + // Calculate and update progress based on Robocopy output + int progress = CalculateProgressFromRobocopy(e.Data); + UpdateProgress(progress); + } + }; + + robocopyProcess.BeginOutputReadLine(); + + // Wait for the process to finish + await robocopyProcess.WaitForExitAsync(); + } + + // Step 5: Get the path to the original WIM file (from the ISO) + string wimFilePath = Path.Combine(isoDriveLetter, "sources", "install.wim"); + _logger.Log("Preparing install.wim... This may take a moment, please wait.", Color.Blue); + + // Step 4: Split Install.wim + UpdateStatusLabel(); // Updates to "4/5 - Split Install.wim" + if (File.Exists(wimFilePath)) + { + // Step 7: Define the path for the split files + string swmFilePath = Path.Combine(usbDrive, "sources", "install.swm"); // First split file + + // Step 8: Dism command to split WIM + string splitDismCommand = $"/C Dism /Split-Image /ImageFile:\"{wimFilePath}\" /SWMFile:\"{swmFilePath}\" /FileSize:3000"; + + // Execute the command + ProcessStartInfo splitInfo = new ProcessStartInfo("cmd.exe", splitDismCommand) + { + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + // Step 5: Finalize Installation Media + UpdateStatusLabel(); // Updates to 5/5 - Finalize Installation Media + + using (Process splitProcess = Process.Start(splitInfo)) + { + splitProcess.OutputDataReceived += (s, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + _logger.Log(e.Data, Color.Black); // Log the output from Dism + } + }; + + splitProcess.BeginOutputReadLine(); + + // Wait for the process to finish + await splitProcess.WaitForExitAsync(); + _logger.Log($"WIM file split completed with exit code: {splitProcess.ExitCode}", Color.Blue); + } + } + else + { + _logger.Log($"WIM file not found at {wimFilePath}.", Color.Red); + } + } + catch (Exception ex) + { + _logger.Log($"Error copying ISO: {ex.Message}", Color.Red); + } + + MessageBox.Show("Your installation media is ready! You can now proceed with the installation.", "Installation Media", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + /// + /// Retrieves the drive letter of the currently mounted drive. + /// + /// The drive letter of the mounted CD/DVD drive, or null if not found. + private async Task GetMountedDriveLetterAsync() + { + try + { + // List all the drives to find the mounted CD/DVD drive + var drives = DriveInfo.GetDrives(); + + foreach (var drive in drives) + { + // Check if the drive is a CD/DVD and if it's mounted + if (drive.DriveType == DriveType.CDRom && drive.IsReady) + { + // Return the letter of the mounted drive + return drive.Name; // Returns "D:\", "E:\", etc. + } + } + + return null; // Return null if no mounted CD/DVD drive is found + } + catch (Exception ex) + { + _logger.Log($"Error getting mounted drive letter: {ex.Message}", Color.Crimson); + return null; + } + } + + /// + /// Downloads the Microsoft Media Creation Tool from https://go.microsoft.com/fwlink/?linkid=2156295 + /// + /// The URL of the Media Creation Tool. + /// A task representing the asynchronous operation. + public async Task DownloadMediaCreationTool() + { + string downloadUrl = "https://go.microsoft.com/fwlink/?linkid=2156295"; + + using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + { + saveFileDialog.Filter = "Executable Files (*.exe)|*.exe"; + saveFileDialog.Title = "Save Media Creation Tool"; + saveFileDialog.FileName = "MediaCreationTool.exe"; + + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + string destinationPath = saveFileDialog.FileName; + + try + { + _logger.Log("Preparing to download Media Creation Tool...", Color.Black); + _logger.Log("Download may take some time, please wait...", Color.Orange); + + var response = await httpClient.GetAsync(downloadUrl); + response.EnsureSuccessStatusCode(); + + using (var fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + await response.Content.CopyToAsync(fileStream); + } + + _logger.Log("Download completed successfully!", Color.Green); + + // Start the downloaded Media Creation Tool + _logger.Log("Starting Media Creation Tool...", Color.Black); + Process.Start(new ProcessStartInfo + { + FileName = destinationPath, + UseShellExecute = true // run .exe files + }); + } + catch (Exception ex) + { + _logger.Log($"An error occurred while downloading: {ex.Message}", Color.Red); + } + } + else + { + _logger.Log("Download canceled by user.", Color.Red); + } + } + } + + /// + /// Calculates progress based on Robocopy output + /// + private int CalculateProgressFromRobocopy(string robocopyOutput) + { + // Find the percentage completion in Robocopy output + var match = Regex.Match(robocopyOutput, @"(\d+)\%"); + + if (match.Success) + { + // Extract the percentage number from the match and convert it to an integer + if (int.TryParse(match.Groups[1].Value, out int progress)) + { + return progress; + } + } + + return 0; // Return 0 if no percentage was found + } + + /// + /// Copy the ISO to the USB drive and optionally create an unattend.xml file + /// + /// + /// + /// + /// + public async Task CopyISOWithUnattendAsync(string usbDrive, string isoPath, bool createUnattend) + { + await CopyISOAsync(usbDrive, isoPath); + + if (createUnattend) + { + CreateUnattendXml(usbDrive); // Only create unattend.xml if checkbox is checked + } + } + + /// + /// // Create unattend.xml file in the sources\$OEM$\$$\Panther directory + /// + /// + public void CreateUnattendXml(string usbDrive) + { + string unattendDir = Path.Combine(usbDrive, "sources", "$OEM$", "$$", "Panther"); + Directory.CreateDirectory(unattendDir); // Create the directory if it doesn't exist + + string unattendPath = Path.Combine(unattendDir, "unattend.xml"); + + // Check if the file already exists + if (!File.Exists(unattendPath)) + { + // Create the unattend.xml content + string xmlContent = @" + + + + + + + + + +1 +reg add HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f + + +2 +reg add HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f + + +3 +reg add HKLM\SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f + + + + + + + + +1 +reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE /v BypassNRO /t REG_DWORD /d 1 /f + + + + +"; + + File.WriteAllText(unattendPath, xmlContent); + _logger.Log("Created unattend.xml in the sources\\$OEM$\\$$\\Panther directory.", Color.Green); + } + else + { + _logger.Log("unattend.xml already exists in the sources\\$OEM$\\$$\\Panther directory.", Color.Blue); + } + } + } +} \ No newline at end of file diff --git a/FlybyScript/Views/ExperienceView.Designer.cs b/FlybyScript/Views/ExperienceView.Designer.cs index aa3102e..186d5d7 100644 --- a/FlybyScript/Views/ExperienceView.Designer.cs +++ b/FlybyScript/Views/ExperienceView.Designer.cs @@ -29,8 +29,14 @@ private void InitializeComponent() { this.btnBack = new System.Windows.Forms.Button(); + this.featurePanel = new System.Windows.Forms.FlowLayoutPanel(); + this.rtbDescription = new System.Windows.Forms.RichTextBox(); + this.lblHeader = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.btnRevert = new System.Windows.Forms.Button(); + this.btnApply = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.featurePanel.SuspendLayout(); this.SuspendLayout(); // // btnBack @@ -39,53 +45,136 @@ this.btnBack.FlatAppearance.BorderColor = System.Drawing.SystemColors.Control; this.btnBack.FlatAppearance.BorderSize = 0; this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnBack.Font = new System.Drawing.Font("Segoe MDL2 Assets", 9.75F, System.Drawing.FontStyle.Bold); + this.btnBack.Font = new System.Drawing.Font("Segoe MDL2 Assets", 14F, System.Drawing.FontStyle.Bold); this.btnBack.ForeColor = System.Drawing.Color.DarkGray; this.btnBack.Location = new System.Drawing.Point(3, 3); this.btnBack.Name = "btnBack"; - this.btnBack.Size = new System.Drawing.Size(29, 25); + this.btnBack.Size = new System.Drawing.Size(34, 29); this.btnBack.TabIndex = 231; this.btnBack.Text = "..."; this.btnBack.UseVisualStyleBackColor = true; this.btnBack.Click += new System.EventHandler(this.btnBack_Click); // + // featurePanel + // + this.featurePanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.featurePanel.AutoScroll = true; + this.featurePanel.Controls.Add(this.rtbDescription); + this.featurePanel.Location = new System.Drawing.Point(69, 170); + this.featurePanel.Name = "featurePanel"; + this.featurePanel.Size = new System.Drawing.Size(852, 365); + this.featurePanel.TabIndex = 232; + // + // rtbDescription + // + this.rtbDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtbDescription.BackColor = System.Drawing.Color.Silver; + this.rtbDescription.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtbDescription.Location = new System.Drawing.Point(3, 3); + this.rtbDescription.Name = "rtbDescription"; + this.rtbDescription.Size = new System.Drawing.Size(345, 55); + this.rtbDescription.TabIndex = 233; + this.rtbDescription.Text = ""; + this.rtbDescription.Visible = false; + // + // lblHeader + // + this.lblHeader.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblHeader.AutoEllipsis = true; + this.lblHeader.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 21.25F); + this.lblHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.lblHeader.Location = new System.Drawing.Point(69, 22); + this.lblHeader.Name = "lblHeader"; + this.lblHeader.Size = new System.Drawing.Size(771, 84); + this.lblHeader.TabIndex = 234; + this.lblHeader.Text = "Choose privacy settings for your device"; + // // label1 // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.label1.AutoEllipsis = true; - this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); - this.label1.Location = new System.Drawing.Point(131, 201); + this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(73, 66); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(780, 82); - this.label1.TabIndex = 232; - this.label1.Text = "This page is under development and will assist you in personalizing your installa" + - "tion."; + this.label1.Size = new System.Drawing.Size(837, 66); + this.label1.TabIndex = 235; + this.label1.Text = "Good news!\r\nWith these privacy settings, you\'re in control of what’s shared and s" + + "hown within Microsoft.\r\n\r\nTo accept, choose \"Accept and Apply.\" If you prefer de" + + "fault settings, select \"Decline.\""; // - // linkLabel1 + // btnRevert // - this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.linkLabel1.AutoEllipsis = true; - this.linkLabel1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 10.25F); - this.linkLabel1.LinkColor = System.Drawing.Color.Black; - this.linkLabel1.Location = new System.Drawing.Point(137, 310); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(677, 19); - this.linkLabel1.TabIndex = 233; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "In the meantime, you can enhance this app with xd-AntiSpy plugins by placing them" + - " in the \'upgraider\' folder."; - this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + this.btnRevert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnRevert.AutoEllipsis = true; + this.btnRevert.BackColor = System.Drawing.Color.White; + this.btnRevert.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnRevert.FlatAppearance.BorderColor = System.Drawing.Color.Gray; + this.btnRevert.FlatAppearance.BorderSize = 2; + this.btnRevert.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnRevert.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnRevert.Font = new System.Drawing.Font("Segoe UI Variable Small", 10F); + this.btnRevert.Location = new System.Drawing.Point(473, 565); + this.btnRevert.Name = "btnRevert"; + this.btnRevert.Size = new System.Drawing.Size(220, 40); + this.btnRevert.TabIndex = 238; + this.btnRevert.TabStop = false; + this.btnRevert.Text = "Decline"; + this.btnRevert.UseVisualStyleBackColor = false; + this.btnRevert.Click += new System.EventHandler(this.btnRevert_Click); + // + // btnApply + // + this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnApply.BackColor = System.Drawing.Color.White; + this.btnApply.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnApply.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnApply.FlatAppearance.BorderSize = 2; + this.btnApply.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnApply.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnApply.Font = new System.Drawing.Font("Segoe UI Variable Small", 10F); + this.btnApply.Location = new System.Drawing.Point(699, 565); + this.btnApply.Name = "btnApply"; + this.btnApply.Size = new System.Drawing.Size(222, 40); + this.btnApply.TabIndex = 237; + this.btnApply.TabStop = false; + this.btnApply.Text = "Accept and apply"; + this.btnApply.UseCompatibleTextRendering = true; + this.btnApply.UseVisualStyleBackColor = false; + this.btnApply.Click += new System.EventHandler(this.btnApply_Click); + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoEllipsis = true; + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Segoe UI Variable Small Semibol", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(84, 142); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(158, 16); + this.label2.TabIndex = 239; + this.label2.Text = "Last updated October 2024"; // // ExperienceView // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.linkLabel1); + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.label2); + this.Controls.Add(this.btnRevert); + this.Controls.Add(this.btnApply); this.Controls.Add(this.label1); + this.Controls.Add(this.lblHeader); + this.Controls.Add(this.featurePanel); this.Controls.Add(this.btnBack); this.Name = "ExperienceView"; - this.Size = new System.Drawing.Size(1043, 484); + this.Size = new System.Drawing.Size(959, 631); + this.featurePanel.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -94,7 +183,12 @@ #endregion private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.FlowLayoutPanel featurePanel; + private System.Windows.Forms.RichTextBox rtbDescription; + private System.Windows.Forms.Label lblHeader; private System.Windows.Forms.Label label1; - private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Button btnRevert; + private System.Windows.Forms.Button btnApply; + private System.Windows.Forms.Label label2; } } diff --git a/FlybyScript/Views/ExperienceView.cs b/FlybyScript/Views/ExperienceView.cs index afb3701..104f420 100644 --- a/FlybyScript/Views/ExperienceView.cs +++ b/FlybyScript/Views/ExperienceView.cs @@ -1,38 +1,118 @@ -using System; +using FlybyScript; +using Settings.Ads; +using Settings.Privacy; +using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace Views { public partial class ExperienceView : UserControl { + private Logger logger; + private List features; + public ExperienceView() { InitializeComponent(); SetStyle(); + InitializeFeatures(); + LoadFeatures(); } private void SetStyle() { - // Segoe MDL2 Assets + // Segoe MDL2 Assets assets btnBack.Text = "\uE72B"; } + private void InitializeFeatures() + { + // Initialize logger + logger = new Logger(rtbDescription); + + // Initialize the list of features + features = new List + { + new FindMyDevice(logger), + new PrivacyExperience(logger), + new Telemetry(logger), + new FileExplorerAds(logger), + new FinishSetupAds(logger), + new LockScreenAds(logger), + new PersonalizedAds(logger), + new SettingsAds(logger), + new StartmenuAds(logger), + new TailoredExperiences(logger), + new TipsAndSuggestions(logger), + new WelcomeExperienceAds(logger) + }; + } + + private void LoadFeatures() + { + // Ensure featurePanel is not null + if (featurePanel == null) + { + MessageBox.Show("FeaturePanel is not initialized. Please check the designer.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // Clear any existing controls in the featurePanel + featurePanel.Controls.Clear(); + + // Populate featurePanel with FeaturePanels + foreach (var feature in features) + { + var featurePanelInstance = new FeaturePanel(feature, logger) + { + Width = featurePanel.Width - 50, // Set the width to match the parent featurePanel + Height = 160, + BorderStyle = BorderStyle.None, + BackColor = Color.FromArgb(245, 245, 245), + Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, featurePanel.Width, 160, 20, 20)) // Rounded corners + }; + + featurePanel.Controls.Add(featurePanelInstance); + } + } + private void btnBack_Click(object sender, EventArgs e) { SwitchView.GoBack(this.Parent as Panel); } - private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + // Import rounded corners + [System.Runtime.InteropServices.DllImport("gdi32.dll")] + private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse); + + private void btnApply_Click(object sender, EventArgs e) { - Process.Start("https://github.com/builtbybel/xd-AntiSpy/tree/main/plugins"); + foreach (var feature in features) + { + if (!feature.CheckFeature()) // If feature is not enabled + { + feature.DoFeature(); // Apply feature + logger.Log($"{feature.ID()} enabled.", Color.Green); + } + } + LoadFeatures(); + MessageBox.Show("All features have been applied.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void btnRevert_Click(object sender, EventArgs e) + { + foreach (var feature in features) + { + if (feature.CheckFeature()) + { + feature.UndoFeature(); // Revert feature + logger.Log($"{feature.ID()} reverted.", Color.Red); + } + } + LoadFeatures(); + MessageBox.Show("All features have been reverted.", "Revert Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } \ No newline at end of file diff --git a/FlybyScript/Views/MediaView.Designer.cs b/FlybyScript/Views/MediaView.Designer.cs new file mode 100644 index 0000000..f4cd03f --- /dev/null +++ b/FlybyScript/Views/MediaView.Designer.cs @@ -0,0 +1,341 @@ +namespace Views +{ + partial class MediaView + { + /// + /// Erforderliche Designervariable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Verwendete Ressourcen bereinigen. + /// + /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Komponenten-Designer generierter Code + + /// + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// + private void InitializeComponent() + { + this.btnBack = new System.Windows.Forms.Button(); + this.rtbLog = new System.Windows.Forms.RichTextBox(); + this.comboBoxDrives = new System.Windows.Forms.ComboBox(); + this.btnStart = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.btnSelect = new System.Windows.Forms.Button(); + this.label6 = new System.Windows.Forms.Label(); + this.btnMCT = new System.Windows.Forms.Button(); + this.label7 = new System.Windows.Forms.Label(); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.lblStatus = new System.Windows.Forms.Label(); + this.checkCreateUnattend = new System.Windows.Forms.CheckBox(); + this.comboBoxDriveLetters = new System.Windows.Forms.ComboBox(); + this.linkShowDiskList = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // btnBack + // + this.btnBack.AutoSize = true; + this.btnBack.FlatAppearance.BorderColor = System.Drawing.SystemColors.Control; + this.btnBack.FlatAppearance.BorderSize = 0; + this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnBack.Font = new System.Drawing.Font("Segoe MDL2 Assets", 14F, System.Drawing.FontStyle.Bold); + this.btnBack.ForeColor = System.Drawing.Color.DarkGray; + this.btnBack.Location = new System.Drawing.Point(3, 3); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(34, 29); + this.btnBack.TabIndex = 231; + this.btnBack.Text = "..."; + this.btnBack.UseVisualStyleBackColor = true; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); + // + // rtbLog + // + this.rtbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtbLog.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230))))); + this.rtbLog.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtbLog.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 9.75F); + this.rtbLog.Location = new System.Drawing.Point(59, 362); + this.rtbLog.Name = "rtbLog"; + this.rtbLog.Size = new System.Drawing.Size(835, 148); + this.rtbLog.TabIndex = 234; + this.rtbLog.Text = "Ready"; + // + // comboBoxDrives + // + this.comboBoxDrives.Font = new System.Drawing.Font("Segoe UI Variable Small", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.comboBoxDrives.FormattingEnabled = true; + this.comboBoxDrives.Location = new System.Drawing.Point(59, 98); + this.comboBoxDrives.Name = "comboBoxDrives"; + this.comboBoxDrives.Size = new System.Drawing.Size(121, 25); + this.comboBoxDrives.TabIndex = 235; + // + // btnStart + // + this.btnStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnStart.BackColor = System.Drawing.Color.White; + this.btnStart.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnStart.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnStart.FlatAppearance.BorderSize = 2; + this.btnStart.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnStart.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnStart.Font = new System.Drawing.Font("Segoe UI Variable Small", 10F); + this.btnStart.Location = new System.Drawing.Point(671, 562); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(205, 40); + this.btnStart.TabIndex = 236; + this.btnStart.TabStop = false; + this.btnStart.Text = "Start"; + this.btnStart.UseCompatibleTextRendering = true; + this.btnStart.UseVisualStyleBackColor = false; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // label1 + // + this.label1.AutoEllipsis = true; + this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.label1.Location = new System.Drawing.Point(55, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(182, 32); + this.label1.TabIndex = 237; + this.label1.Tag = ""; + this.label1.Text = "Drive Properties"; + // + // label2 + // + this.label2.AutoEllipsis = true; + this.label2.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(57, 80); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(79, 15); + this.label2.TabIndex = 238; + this.label2.Tag = ""; + this.label2.Text = "Device ID"; + // + // label5 + // + this.label5.AutoEllipsis = true; + this.label5.Font = new System.Drawing.Font("Segoe UI Variable Small", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.label5.Location = new System.Drawing.Point(55, 328); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(114, 31); + this.label5.TabIndex = 241; + this.label5.Tag = ""; + this.label5.Text = "Status"; + // + // btnSelect + // + this.btnSelect.AutoEllipsis = true; + this.btnSelect.BackColor = System.Drawing.Color.White; + this.btnSelect.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnSelect.FlatAppearance.BorderColor = System.Drawing.Color.Gray; + this.btnSelect.FlatAppearance.BorderSize = 2; + this.btnSelect.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnSelect.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnSelect.Font = new System.Drawing.Font("Segoe UI Variable Small", 9F); + this.btnSelect.Location = new System.Drawing.Point(59, 241); + this.btnSelect.Name = "btnSelect"; + this.btnSelect.Size = new System.Drawing.Size(132, 28); + this.btnSelect.TabIndex = 242; + this.btnSelect.TabStop = false; + this.btnSelect.Text = "Select"; + this.btnSelect.UseCompatibleTextRendering = true; + this.btnSelect.UseVisualStyleBackColor = false; + this.btnSelect.Click += new System.EventHandler(this.btnSelect_Click); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label6.Location = new System.Drawing.Point(57, 223); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(76, 15); + this.label6.TabIndex = 243; + this.label6.Tag = ""; + this.label6.Text = "Select ISO file"; + // + // btnMCT + // + this.btnMCT.AutoEllipsis = true; + this.btnMCT.BackColor = System.Drawing.Color.White; + this.btnMCT.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnMCT.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(65)))), ((int)(((byte)(17))))); + this.btnMCT.FlatAppearance.BorderSize = 2; + this.btnMCT.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnMCT.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnMCT.Font = new System.Drawing.Font("Segoe UI Variable Small", 9F); + this.btnMCT.Location = new System.Drawing.Point(235, 241); + this.btnMCT.Name = "btnMCT"; + this.btnMCT.Size = new System.Drawing.Size(205, 28); + this.btnMCT.TabIndex = 244; + this.btnMCT.TabStop = false; + this.btnMCT.Text = "Media Creation Tool (Microsoft)"; + this.btnMCT.UseCompatibleTextRendering = true; + this.btnMCT.UseVisualStyleBackColor = false; + this.btnMCT.Click += new System.EventHandler(this.btnMCT_Click); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label7.Location = new System.Drawing.Point(232, 223); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(85, 15); + this.label7.TabIndex = 245; + this.label7.Tag = ""; + this.label7.Text = "or prepare with"; + // + // progressBar + // + this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressBar.Location = new System.Drawing.Point(60, 516); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(834, 23); + this.progressBar.TabIndex = 246; + // + // lblStatus + // + this.lblStatus.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.lblStatus.AutoEllipsis = true; + this.lblStatus.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230))))); + this.lblStatus.Font = new System.Drawing.Font("Segoe UI Variable Small Semibol", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblStatus.Location = new System.Drawing.Point(361, 519); + this.lblStatus.Name = "lblStatus"; + this.lblStatus.Size = new System.Drawing.Size(226, 18); + this.lblStatus.TabIndex = 247; + this.lblStatus.Tag = ""; + this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // checkCreateUnattend + // + this.checkCreateUnattend.Appearance = System.Windows.Forms.Appearance.Button; + this.checkCreateUnattend.AutoEllipsis = true; + this.checkCreateUnattend.FlatAppearance.BorderColor = System.Drawing.Color.Gray; + this.checkCreateUnattend.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.checkCreateUnattend.Font = new System.Drawing.Font("Segoe UI Variable Small", 8F); + this.checkCreateUnattend.Location = new System.Drawing.Point(72, 275); + this.checkCreateUnattend.Name = "checkCreateUnattend"; + this.checkCreateUnattend.Size = new System.Drawing.Size(194, 25); + this.checkCreateUnattend.TabIndex = 250; + this.checkCreateUnattend.Text = "Skip Hardware limits and go local"; + this.checkCreateUnattend.UseVisualStyleBackColor = true; + this.checkCreateUnattend.Visible = false; + this.checkCreateUnattend.CheckedChanged += new System.EventHandler(this.checkCreateUnattend_CheckedChanged); + // + // comboBoxDriveLetters + // + this.comboBoxDriveLetters.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxDriveLetters.Font = new System.Drawing.Font("Segoe UI Variable Small", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.comboBoxDriveLetters.FormattingEnabled = true; + this.comboBoxDriveLetters.Location = new System.Drawing.Point(210, 98); + this.comboBoxDriveLetters.Name = "comboBoxDriveLetters"; + this.comboBoxDriveLetters.Size = new System.Drawing.Size(121, 25); + this.comboBoxDriveLetters.TabIndex = 251; + // + // linkShowDiskList + // + this.linkShowDiskList.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.linkShowDiskList.Location = new System.Drawing.Point(60, 126); + this.linkShowDiskList.Name = "linkShowDiskList"; + this.linkShowDiskList.Size = new System.Drawing.Size(177, 16); + this.linkShowDiskList.TabIndex = 252; + this.linkShowDiskList.TabStop = true; + this.linkShowDiskList.Text = "Help me identify the device id"; + this.linkShowDiskList.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkShowDiskList_LinkClicked); + // + // label3 + // + this.label3.AutoEllipsis = true; + this.label3.Font = new System.Drawing.Font("Segoe UI Variable Small", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.label3.Location = new System.Drawing.Point(55, 177); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(182, 32); + this.label3.TabIndex = 253; + this.label3.Tag = ""; + this.label3.Text = "Create Media"; + // + // label4 + // + this.label4.AutoEllipsis = true; + this.label4.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.Location = new System.Drawing.Point(207, 80); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(79, 15); + this.label4.TabIndex = 254; + this.label4.Tag = ""; + this.label4.Text = "Device Letter"; + // + // InstallationMediaView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkShowDiskList); + this.Controls.Add(this.comboBoxDriveLetters); + this.Controls.Add(this.checkCreateUnattend); + this.Controls.Add(this.lblStatus); + this.Controls.Add(this.progressBar); + this.Controls.Add(this.label7); + this.Controls.Add(this.btnMCT); + this.Controls.Add(this.label6); + this.Controls.Add(this.btnSelect); + this.Controls.Add(this.label5); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnStart); + this.Controls.Add(this.comboBoxDrives); + this.Controls.Add(this.rtbLog); + this.Controls.Add(this.btnBack); + this.Name = "InstallationMediaView"; + this.Size = new System.Drawing.Size(959, 631); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.RichTextBox rtbLog; + private System.Windows.Forms.ComboBox comboBoxDrives; + private System.Windows.Forms.Button btnStart; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Button btnSelect; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button btnMCT; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Label lblStatus; + private System.Windows.Forms.CheckBox checkCreateUnattend; + private System.Windows.Forms.ComboBox comboBoxDriveLetters; + private System.Windows.Forms.LinkLabel linkShowDiskList; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + } +} diff --git a/FlybyScript/Views/MediaView.cs b/FlybyScript/Views/MediaView.cs new file mode 100644 index 0000000..8f534ed --- /dev/null +++ b/FlybyScript/Views/MediaView.cs @@ -0,0 +1,246 @@ +using FlybyScript; +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Views +{ + public partial class MediaView : UserControl + { + private USBManagement usbManagement; + private Logger logger; + + private string selectedIsoPath; + + public MediaView() + { + InitializeComponent(); + SetStyle(); + + InitializeUSBDriveList(); + logger = new Logger(rtbLog); + usbManagement = new USBManagement(logger, updateLabelStatus, progressBar); + } + + private void SetStyle() + { + // Segoe MDL2 Assets + btnBack.Text = "\uE72B"; + } + + private void updateLabelStatus(string statusText) + { + if (lblStatus.InvokeRequired) + { + lblStatus.Invoke(new Action(() => lblStatus.Text = statusText)); + } + else + { + lblStatus.Text = statusText; + } + } + + private void InitializeUSBDriveList() + { + // Initialize disk numbers + comboBoxDrives.Items.Clear(); + comboBoxDrives.Items.AddRange(new object[] { "Select (e.g., 1, 2, 3...)", "1", "2", "3" }); + comboBoxDrives.SelectedIndex = 0; + + // Initialize removable drives + comboBoxDriveLetters.Items.Clear(); + var removableDrives = DriveInfo.GetDrives() + .Where(d => d.DriveType == DriveType.Removable) + .Select(d => d.Name) + .ToArray(); + + if (removableDrives.Any()) + { + comboBoxDriveLetters.Items.AddRange(removableDrives); + comboBoxDriveLetters.SelectedIndex = 0; + } + else + { + //MessageBox.Show("No removable drives found.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + comboBoxDriveLetters.Enabled = + comboBoxDrives.Enabled = false; + } + } + + private async Task ShowDiskList() + { + try + { + // Use chcp command to get the current code page of the user's system + ProcessStartInfo chcpInfo = new ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = "/C chcp", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + string codePageOutput; + using (Process chcpProcess = Process.Start(chcpInfo)) + { + codePageOutput = await chcpProcess.StandardOutput.ReadToEndAsync(); + chcpProcess.WaitForExit(); + } + + // Extract the code page number from chcp output + int codePage = 850; // Default to 850 if detection fails + var match = System.Text.RegularExpressions.Regex.Match(codePageOutput, @"\d+"); + if (match.Success) + { + codePage = int.Parse(match.Value); // Parse our detected code page + } + + ProcessStartInfo processInfo = new ProcessStartInfo + { + FileName = "diskpart.exe", + RedirectStandardInput = true, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + StandardOutputEncoding = Encoding.GetEncoding(codePage) + }; + + // Start the process + using (Process process = Process.Start(processInfo)) + { + using (StreamWriter writer = process.StandardInput) + { + if (writer.BaseStream.CanWrite) + { + writer.WriteLine("list disk"); + } + } + + string output = await process.StandardOutput.ReadToEndAsync(); + process.WaitForExit(); + MessageBox.Show(output, "Available Disks", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred while listing disks: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + // Event handler for starting the format and copy process + private async void btnStart_Click(object sender, EventArgs e) + { + btnStart.Enabled = false; // Disable the Start button + + // Validate Disk Number + if (string.IsNullOrEmpty(comboBoxDrives.Text) || !int.TryParse(comboBoxDrives.Text, out _)) + { + logger.Log("Please enter a valid Disk Number.", Color.Red); + btnStart.Enabled = true; // Re-enable the button + return; + } + + // Validate Drive Letter + if (string.IsNullOrEmpty(comboBoxDriveLetters.SelectedItem?.ToString())) + { + logger.Log("Please select a valid Drive Letter.", Color.Red); + btnStart.Enabled = true; + return; + } + + string diskNumber = comboBoxDrives.Text.Trim(); // Get the disk number from the ComboBox + string driveLetter = comboBoxDriveLetters.SelectedItem.ToString().Trim(); // Get the selected drive letter + + logger.Log($"Starting to format Disk {diskNumber} and copy to Drive {driveLetter}...", Color.Black); + + try + { + // Format the drive using the disk number + await usbManagement.FormatDriveAsync(diskNumber); // Pass the disk number + logger.Log($"Disk {diskNumber} formatted successfully.", Color.Black); + logger.Log($"Disk {diskNumber} is now bootable.", Color.Black); + + // Copy ISO and create unattend.xml if checked + bool createUnattend = checkCreateUnattend.Checked; + await usbManagement.CopyISOWithUnattendAsync(driveLetter, selectedIsoPath, createUnattend); // Use the drive letter for copying + + logger.Log("Process completed!", Color.Green); + } + catch (Exception ex) + { + logger.Log($"An error occurred during the process: {ex.Message}", Color.Red); + } + finally + { + btnStart.Enabled = true; + } + } + + private void btnSelect_Click(object sender, EventArgs e) + { + using (OpenFileDialog openFileDialog = new OpenFileDialog()) + { + openFileDialog.Filter = "ISO Files (*.iso)|*.iso|All Files (*.*)|*.*"; + openFileDialog.Title = "Select an ISO File"; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + selectedIsoPath = openFileDialog.FileName; + logger.Log($"Selected ISO file: {selectedIsoPath}", Color.Black); + + checkCreateUnattend.Visible = true; // Show the checkbox to create unattend.xml + } + else + { + logger.Log("ISO file selection was cancelled.", Color.Red); + } + } + } + + private void checkCreateUnattend_CheckedChanged(object sender, EventArgs e) + { + if (checkCreateUnattend.Checked) + { + checkCreateUnattend.BackColor = Color.LightGreen; + + MessageBox.Show( + "You have enabled the bypass for Windows 11 hardware requirements.\n\n" + + "This will: \n" + + "- Skip TPM 2.0 checks\n" + + "- Bypass the 4GB+ RAM requirement\n" + + "- Disable Secure Boot requirement\n" + + "- Allow creating a local account (no online setup required)\n\n" + + "During installation, Windows will offer the 'I don't have internet' option for offline account creation.", + "Bypass Enabled", + MessageBoxButtons.OK, + MessageBoxIcon.Information + ); + } + else + { + checkCreateUnattend.BackColor = Color.White; + } + } + + private async void linkShowDiskList_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + await ShowDiskList(); + } + + private async void btnMCT_Click(object sender, EventArgs e) + { + await usbManagement.DownloadMediaCreationTool(); + } + + private void btnBack_Click(object sender, EventArgs e) + { + SwitchView.GoBack(this.Parent as Panel); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Views/MediaView.resx b/FlybyScript/Views/MediaView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/FlybyScript/Views/MediaView.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file