219 lines
9.4 KiB
C#
219 lines
9.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using Views;
|
|
|
|
namespace FlybyScript
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
private Dictionary<TreeNode, bool> pendingChanges = new Dictionary<TreeNode, bool>(); // Store pending changes
|
|
private PSPatcher PSPatcher;
|
|
|
|
private Logger logger;
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// Initialize the logger
|
|
logger = new Logger(rtbDescription);
|
|
|
|
// Set the default view to the main panel
|
|
SwitchView.DefaultView = panelMain;
|
|
}
|
|
|
|
private async void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
// Add NativePatcher parent node
|
|
TreeNode nativePatcherNode = new TreeNode("Native (Recommended)");
|
|
treeSettings.Nodes.Add(nativePatcherNode);
|
|
|
|
// Add Method 1 as a child of NativePatcher
|
|
TreeNode method1Node = new TreeNode("(Method 1) Inplace Upgrade via Server Setup");
|
|
method1Node.Tag = "Method1";
|
|
nativePatcherNode.Nodes.Add(method1Node);
|
|
|
|
// Add ScriptPatcher parent node
|
|
await ScriptPatcher.LoadPlugins("upgraider", treeSettings.Nodes, logger);
|
|
|
|
// Add PSPatcher parent node (for Dependencies)
|
|
PSPatcher = new PSPatcher();
|
|
PSPatcher.LoadPowerShellPlugins(treeSettings);
|
|
|
|
// Expand all nodes
|
|
ExpandAllNodes(treeSettings.Nodes);
|
|
}
|
|
|
|
private void ExpandAllNodes(TreeNodeCollection nodes)
|
|
{
|
|
foreach (TreeNode node in nodes)
|
|
{
|
|
node.Expand();
|
|
ExpandAllNodes(node.Nodes);
|
|
}
|
|
}
|
|
|
|
private void treeSettings_AfterCheck(object sender, TreeViewEventArgs e)
|
|
{
|
|
// Check if the node's checked status has changed
|
|
if (e.Node.Checked)
|
|
{
|
|
// Add the node and set its status to true (enabled)
|
|
pendingChanges[e.Node] = true;
|
|
e.Node.BackColor = Color.LightGreen; // Mark the node as active
|
|
|
|
// Check the type of node (either JSONPluginLoader/Patch or PowerShell script)
|
|
if (e.Node.Tag is ScriptPatcher jsonPlugin)
|
|
{
|
|
logger.Log($"Patch activated: {jsonPlugin.PlugID}", Color.Black);
|
|
}
|
|
else if (e.Node.Tag is string psScriptPath)
|
|
{
|
|
logger.Log($"PowerShell script activated: {Path.GetFileName(psScriptPath)}", Color.Black);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Add the node and set its status to false (disabled)
|
|
pendingChanges[e.Node] = false;
|
|
e.Node.BackColor = Color.LightGray; // Mark the node as inactive
|
|
|
|
// Check the type of node again (either JSONPluginLoader or PowerShell script)
|
|
if (e.Node.Tag is ScriptPatcher jsonPlugin)
|
|
{
|
|
logger.Log($"Patch deactivated: {jsonPlugin.PlugID}", Color.Crimson);
|
|
}
|
|
else if (e.Node.Tag is string psScriptPath)
|
|
{
|
|
logger.Log($"PowerShell script deactivated: {Path.GetFileName(psScriptPath)}", Color.Crimson);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void btnTogglePatch_Click(object sender, EventArgs e)
|
|
{
|
|
btnTogglePatch.Enabled = false;
|
|
foreach (var entry in pendingChanges)
|
|
{
|
|
var node = entry.Key; // So, The TreeNode
|
|
bool shouldApply = entry.Value; // Whether this patch should be applied (true) or undone (false)
|
|
|
|
// Check if the entry is Method2 and if the patch is enabled
|
|
if (node.Tag?.ToString() == "Method1" && shouldApply)
|
|
{
|
|
// Start Method2 (Setup Server variant)
|
|
logger.Log("(Method 1) Automating Windows 11 Inplace Upgrade...", Color.Blue);
|
|
NativePatcher automation = new NativePatcher(logger);
|
|
await automation.AutomateWindowsInstallation();
|
|
|
|
node.BackColor = Color.LightGreen;
|
|
logger.Log("Method 1 Started: Windows 11 Installation Automated", Color.Black);
|
|
}
|
|
else if (node.Tag is ScriptPatcher plugin)
|
|
{
|
|
if (shouldApply)
|
|
{
|
|
// Apply the patch
|
|
logger.Log($"Applying patch: {plugin.PlugID}", Color.Blue);
|
|
plugin.PlugDoFeature();
|
|
node.BackColor = Color.LightGreen;
|
|
logger.Log($"Activated patch: {plugin.PlugID}", Color.Black);
|
|
}
|
|
else
|
|
{
|
|
// Undo the patch
|
|
logger.Log($"Undoing patch: {plugin.PlugID}", Color.Blue);
|
|
plugin.PlugUndoFeature();
|
|
node.BackColor = Color.LightGray;
|
|
logger.Log($"Deactivated patch: {plugin.PlugID}", Color.Crimson);
|
|
}
|
|
}
|
|
// Handle PowerShell scripts
|
|
else if (node.Tag is string psScriptPath)
|
|
{
|
|
if (shouldApply)
|
|
{
|
|
// Log and execute the PowerShell script
|
|
logger.Log($"Executing PowerShell script: {Path.GetFileName(psScriptPath)}", Color.Blue);
|
|
|
|
var PSPatcher = new PSPatcher();
|
|
await PSPatcher.ExecutePlugin(psScriptPath, logger);
|
|
|
|
node.BackColor = Color.LightGreen;
|
|
logger.Log($"Executed PowerShell script: {Path.GetFileName(psScriptPath)}", Color.Black);
|
|
}
|
|
else
|
|
{
|
|
// Log for deactivation (not reversible for PS scripts)
|
|
logger.Log($"PowerShell script cannot be undone: {Path.GetFileName(psScriptPath)}", Color.Crimson);
|
|
node.BackColor = Color.LightGray;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear pending changes after applying
|
|
pendingChanges.Clear();
|
|
btnTogglePatch.Enabled = true;
|
|
}
|
|
|
|
private void treeSettings_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
TreeNode node = treeSettings.GetNodeAt(e.Location);
|
|
|
|
if (node != null)
|
|
{
|
|
// 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, " +
|
|
"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. " +
|
|
"The app automatically downloads the Windows 11 version 24H2 ISO using the 'Fido' dependency script.\n2. " +
|
|
"The ISO image is mounted automatically.\n3. Simply follow the on-screen instructions to complete the upgrade.\n\n" +
|
|
"**Technical Note:** The POPCNT requirement cannot be bypassed; it is essential for running Windows 11 (24H2), as the operating system requires this feature to be supported by the CPU. " +
|
|
"POPCNT has been included in CPUs since around 2010. However, the patch is expected to work for most users with compatible hardware." +
|
|
"Please do not blame me; I am working within the constraints of what is technically possible."
|
|
;
|
|
}
|
|
else if (node.Tag is ScriptPatcher plugin) // Handle JSON plugin description
|
|
{
|
|
string pluginInfo = $"ID: {plugin.PlugID}\nHow-to:\n{plugin.PlugInfo}";
|
|
rtbDescription.Text = pluginInfo;
|
|
}
|
|
else if (node.Tag is string psScriptPath) // Handle PowerShell script description
|
|
{
|
|
rtbDescription.Clear();
|
|
string scriptInfo = $"PowerShell Script: {Path.GetFileName(psScriptPath)}\nPath: {psScriptPath}";
|
|
rtbDescription.Text = scriptInfo;
|
|
}
|
|
else
|
|
{
|
|
// Clear description if no node is hovered
|
|
rtbDescription.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void linkGitHub_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
{
|
|
Process.Start("https://github.com/builtbybel/Flyby11");
|
|
}
|
|
|
|
private async void btnMountRun_Click(object sender, EventArgs e)
|
|
{
|
|
NativePatcher patcher = new NativePatcher(logger);
|
|
await patcher.RunSetupFromMountedISO();
|
|
}
|
|
|
|
private void linkChangeExperience_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
{
|
|
ExperienceView exprienceView = new ExperienceView();
|
|
SwitchView.SetView(exprienceView, panelForm);
|
|
}
|
|
}
|
|
} |