From c32a6f91227e7857b9d8a322eec554c89b94bb9f Mon Sep 17 00:00:00 2001 From: Vichingo455 Date: Fri, 17 Oct 2025 17:16:41 +0200 Subject: [PATCH] Making big changes --- .../Perfect11.TweaksInterface.csproj | 48 +++++ .../Properties/AssemblyInfo.cs | 33 ++++ Perfect11.TweaksInterface/TweaksInterface.cs | 20 ++ Perfect11.sln | 12 ++ Perfect11/Form1.Designer.cs | 79 +++++++- Perfect11/Form1.cs | 157 ++++++++++++---- Perfect11/Library/PowerShell.cs | 9 +- Perfect11/Library/Utilities.cs | 38 +++- Perfect11/Perfect11.csproj | 9 + Perfect11/Program.cs | 3 - Perfect11/Resources/UWPSystemAppList.txt | 15 +- .../Perfect11.Inbox.UninstallOneDrive.csproj | 55 ++++++ .../Properties/AssemblyInfo.cs | 33 ++++ .../Tweak.cs | 172 ++++++++++++++++++ 14 files changed, 623 insertions(+), 60 deletions(-) create mode 100644 Perfect11.TweaksInterface/Perfect11.TweaksInterface.csproj create mode 100644 Perfect11.TweaksInterface/Properties/AssemblyInfo.cs create mode 100644 Perfect11.TweaksInterface/TweaksInterface.cs create mode 100644 tweaks/Perfect11.Inbox.UninstallOneDrive/Perfect11.Inbox.UninstallOneDrive.csproj create mode 100644 tweaks/Perfect11.Inbox.UninstallOneDrive/Properties/AssemblyInfo.cs create mode 100644 tweaks/Perfect11.Inbox.UninstallOneDrive/Tweak.cs diff --git a/Perfect11.TweaksInterface/Perfect11.TweaksInterface.csproj b/Perfect11.TweaksInterface/Perfect11.TweaksInterface.csproj new file mode 100644 index 0000000..ae401de --- /dev/null +++ b/Perfect11.TweaksInterface/Perfect11.TweaksInterface.csproj @@ -0,0 +1,48 @@ + + + + + Debug + AnyCPU + {B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6} + Library + Properties + Perfect11.TweaksInterface + Perfect11.TweaksInterface + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + none + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Perfect11.TweaksInterface/Properties/AssemblyInfo.cs b/Perfect11.TweaksInterface/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3da5cf0 --- /dev/null +++ b/Perfect11.TweaksInterface/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Perfect11 Tweaks Interface")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Vichingo455")] +[assembly: AssemblyProduct("Perfect11")] +[assembly: AssemblyCopyright("Copyright © 2025 Vichingo455")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b3f8761a-b4b2-4378-9fe8-06bbfc39fce6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Perfect11.TweaksInterface/TweaksInterface.cs b/Perfect11.TweaksInterface/TweaksInterface.cs new file mode 100644 index 0000000..593a435 --- /dev/null +++ b/Perfect11.TweaksInterface/TweaksInterface.cs @@ -0,0 +1,20 @@ +namespace Perfect11.TweaksInterface +{ + public interface IPlugin + { + /// + /// The display name of the plugin. + /// + string Name { get; } + + /// + /// A short description of what the plugin does. + /// + string Description { get; } + + /// + /// Executes the plugin’s main logic. + /// + void Execute(); + } +} diff --git a/Perfect11.sln b/Perfect11.sln index 118d3f1..90409c3 100644 --- a/Perfect11.sln +++ b/Perfect11.sln @@ -5,6 +5,10 @@ VisualStudioVersion = 17.14.36429.23 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perfect11", "Perfect11\Perfect11.csproj", "{B77C3F94-29F7-40D8-BF81-969C1BBAD7A9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perfect11.TweaksInterface", "Perfect11.TweaksInterface\Perfect11.TweaksInterface.csproj", "{B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perfect11.Inbox.UninstallOneDrive", "tweaks\Perfect11.Inbox.UninstallOneDrive\Perfect11.Inbox.UninstallOneDrive.csproj", "{AD55727D-A52C-459D-A316-3459AA80050A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +19,14 @@ Global {B77C3F94-29F7-40D8-BF81-969C1BBAD7A9}.Debug|Any CPU.Build.0 = Debug|Any CPU {B77C3F94-29F7-40D8-BF81-969C1BBAD7A9}.Release|Any CPU.ActiveCfg = Release|Any CPU {B77C3F94-29F7-40D8-BF81-969C1BBAD7A9}.Release|Any CPU.Build.0 = Release|Any CPU + {B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3F8761A-B4B2-4378-9FE8-06BBFC39FCE6}.Release|Any CPU.Build.0 = Release|Any CPU + {AD55727D-A52C-459D-A316-3459AA80050A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD55727D-A52C-459D-A316-3459AA80050A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD55727D-A52C-459D-A316-3459AA80050A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD55727D-A52C-459D-A316-3459AA80050A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Perfect11/Form1.Designer.cs b/Perfect11/Form1.Designer.cs index 4c1639e..5201813 100644 --- a/Perfect11/Form1.Designer.cs +++ b/Perfect11/Form1.Designer.cs @@ -47,11 +47,16 @@ this.removeButton = new ReaLTaiizor.Controls.PoisonButton(); this.addButton = new ReaLTaiizor.Controls.PoisonButton(); this.LstUWP = new ReaLTaiizor.Controls.PoisonListView(); + this.tweaksPage = new ReaLTaiizor.Controls.PoisonTabPage(); + this.tweaksList = new ReaLTaiizor.Controls.PoisonListView(); + this.runTweaks = new ReaLTaiizor.Controls.PoisonButton(); + this.editionLabel = new ReaLTaiizor.Controls.PoisonLabel(); this.theme.SuspendLayout(); this.pages.SuspendLayout(); this.welcomePage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.debloatPage.SuspendLayout(); + this.tweaksPage.SuspendLayout(); this.SuspendLayout(); // // theme @@ -88,10 +93,11 @@ // this.pages.Controls.Add(this.welcomePage); this.pages.Controls.Add(this.debloatPage); + this.pages.Controls.Add(this.tweaksPage); this.pages.Dock = System.Windows.Forms.DockStyle.Fill; this.pages.Location = new System.Drawing.Point(3, 28); this.pages.Name = "pages"; - this.pages.SelectedIndex = 1; + this.pages.SelectedIndex = 2; this.pages.Size = new System.Drawing.Size(1323, 732); this.pages.TabIndex = 1; this.pages.UseSelectable = true; @@ -100,12 +106,13 @@ // this.welcomePage.BackgroundImage = global::Perfect11.Properties.Resources.win11wallpaperdark; this.welcomePage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.welcomePage.Controls.Add(this.editionLabel); this.welcomePage.Controls.Add(this.poisonLabel2); this.welcomePage.Controls.Add(this.pictureBox1); this.welcomePage.Controls.Add(this.poisonLabel1); this.welcomePage.HorizontalScrollbarBarColor = true; this.welcomePage.HorizontalScrollbarHighlightOnWheel = false; - this.welcomePage.HorizontalScrollbarSize = 8; + this.welcomePage.HorizontalScrollbarSize = 11; this.welcomePage.Location = new System.Drawing.Point(4, 38); this.welcomePage.Name = "welcomePage"; this.welcomePage.Size = new System.Drawing.Size(1315, 690); @@ -113,7 +120,7 @@ this.welcomePage.Text = "Welcome"; this.welcomePage.VerticalScrollbarBarColor = true; this.welcomePage.VerticalScrollbarHighlightOnWheel = false; - this.welcomePage.VerticalScrollbarSize = 27; + this.welcomePage.VerticalScrollbarSize = 45; // // poisonLabel2 // @@ -121,7 +128,7 @@ this.poisonLabel2.BackColor = System.Drawing.Color.Transparent; this.poisonLabel2.Location = new System.Drawing.Point(416, 379); this.poisonLabel2.Name = "poisonLabel2"; - this.poisonLabel2.Size = new System.Drawing.Size(492, 40); + this.poisonLabel2.Size = new System.Drawing.Size(465, 38); this.poisonLabel2.TabIndex = 3; this.poisonLabel2.Text = "Perfect11 is a tool made by a guy who loves to optimize Windows.\r\nIt allows to in" + "stalls apps, remove bloatware, configure services and even more."; @@ -163,7 +170,7 @@ this.debloatPage.Controls.Add(this.LstUWP); this.debloatPage.HorizontalScrollbarBarColor = true; this.debloatPage.HorizontalScrollbarHighlightOnWheel = false; - this.debloatPage.HorizontalScrollbarSize = 8; + this.debloatPage.HorizontalScrollbarSize = 11; this.debloatPage.Location = new System.Drawing.Point(4, 38); this.debloatPage.Name = "debloatPage"; this.debloatPage.Size = new System.Drawing.Size(1315, 690); @@ -171,7 +178,7 @@ this.debloatPage.Text = "Debloat"; this.debloatPage.VerticalScrollbarBarColor = true; this.debloatPage.VerticalScrollbarHighlightOnWheel = false; - this.debloatPage.VerticalScrollbarSize = 17; + this.debloatPage.VerticalScrollbarSize = 28; // // BtnRunUninstaller // @@ -209,7 +216,7 @@ this.ChkShowUWPSystem.AutoSize = true; this.ChkShowUWPSystem.Location = new System.Drawing.Point(5, 650); this.ChkShowUWPSystem.Name = "ChkShowUWPSystem"; - this.ChkShowUWPSystem.Size = new System.Drawing.Size(134, 17); + this.ChkShowUWPSystem.Size = new System.Drawing.Size(123, 15); this.ChkShowUWPSystem.TabIndex = 8; this.ChkShowUWPSystem.Text = "Show System Apps"; this.ChkShowUWPSystem.UseSelectable = true; @@ -290,9 +297,60 @@ this.LstUWP.UseSelectable = true; this.LstUWP.View = System.Windows.Forms.View.Tile; // + // tweaksPage + // + this.tweaksPage.Controls.Add(this.runTweaks); + this.tweaksPage.Controls.Add(this.tweaksList); + this.tweaksPage.HorizontalScrollbarBarColor = true; + this.tweaksPage.HorizontalScrollbarHighlightOnWheel = false; + this.tweaksPage.HorizontalScrollbarSize = 10; + this.tweaksPage.Location = new System.Drawing.Point(4, 38); + this.tweaksPage.Name = "tweaksPage"; + this.tweaksPage.Size = new System.Drawing.Size(1315, 690); + this.tweaksPage.TabIndex = 2; + this.tweaksPage.Text = "Tweak"; + this.tweaksPage.VerticalScrollbarBarColor = true; + this.tweaksPage.VerticalScrollbarHighlightOnWheel = false; + this.tweaksPage.VerticalScrollbarSize = 10; + // + // tweaksList + // + this.tweaksList.Font = new System.Drawing.Font("Segoe UI", 12F); + this.tweaksList.FullRowSelect = true; + this.tweaksList.Location = new System.Drawing.Point(0, 0); + this.tweaksList.Name = "tweaksList"; + this.tweaksList.OwnerDraw = true; + this.tweaksList.Size = new System.Drawing.Size(1310, 617); + this.tweaksList.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.tweaksList.TabIndex = 2; + this.tweaksList.UseCompatibleStateImageBehavior = false; + this.tweaksList.UseSelectable = true; + this.tweaksList.Resize += new System.EventHandler(this.tweaksList_Resize); + // + // runTweaks + // + this.runTweaks.FontSize = ReaLTaiizor.Extension.Poison.PoisonButtonSize.Medium; + this.runTweaks.Location = new System.Drawing.Point(1189, 633); + this.runTweaks.Name = "runTweaks"; + this.runTweaks.Size = new System.Drawing.Size(121, 54); + this.runTweaks.TabIndex = 3; + this.runTweaks.Text = "Run Tweaks"; + this.runTweaks.UseSelectable = true; + this.runTweaks.Click += new System.EventHandler(this.runTweaks_Click); + // + // editionLabel + // + this.editionLabel.AutoSize = true; + this.editionLabel.BackColor = System.Drawing.Color.Transparent; + this.editionLabel.Location = new System.Drawing.Point(16, 656); + this.editionLabel.Name = "editionLabel"; + this.editionLabel.Size = new System.Drawing.Size(175, 19); + this.editionLabel.TabIndex = 4; + this.editionLabel.Text = "Perfect11 Community Edition"; + // // Form1 // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 21F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); this.ClientSize = new System.Drawing.Size(1329, 788); @@ -313,6 +371,7 @@ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.debloatPage.ResumeLayout(false); this.debloatPage.PerformLayout(); + this.tweaksPage.ResumeLayout(false); this.ResumeLayout(false); } @@ -337,6 +396,10 @@ private ReaLTaiizor.Controls.PoisonLabel LblInstalledCount; private ReaLTaiizor.Controls.PoisonLabel LblRemoveCount; private ReaLTaiizor.Controls.PoisonButton BtnRunUninstaller; + private ReaLTaiizor.Controls.PoisonTabPage tweaksPage; + private ReaLTaiizor.Controls.PoisonListView tweaksList; + private ReaLTaiizor.Controls.PoisonButton runTweaks; + private ReaLTaiizor.Controls.PoisonLabel editionLabel; } } diff --git a/Perfect11/Form1.cs b/Perfect11/Form1.cs index ee3c3b8..eea515e 100644 --- a/Perfect11/Form1.cs +++ b/Perfect11/Form1.cs @@ -1,15 +1,12 @@ -using Microsoft.VisualBasic.ApplicationServices; -using Perfect11.Library; +using Perfect11.Library; using Perfect11.Properties; +using Perfect11.TweaksInterface; using ReaLTaiizor.Enum.Poison; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Data; -using System.Drawing; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; using System.Windows.Forms; @@ -18,12 +15,15 @@ namespace Perfect11 public partial class Form1 : Form { private List _listSystemApps = new List(); + private List _tweaks = new List(); + private static string AppEdition = "Perfect11 Community Edition"; public Form1() { InitializeComponent(); - DarkMode(true); + InitializeDarkMode(); GetUWPSystem(); GetUWP(); + InitializeTweaks(); } public void DarkMode(bool status) { @@ -44,28 +44,47 @@ namespace Perfect11 addButton.Theme = ThemeStyle.Dark; removeAllButton.Theme = ThemeStyle.Dark; removeButton.Theme = ThemeStyle.Dark; + welcomePage.BackgroundImage = Resources.win11wallpaperdark; + tweaksPage.Theme = ThemeStyle.Dark; + tweaksList.Theme = ThemeStyle.Dark; + runTweaks.Theme = ThemeStyle.Dark; + editionLabel.Theme = ThemeStyle.Dark; } else { pages.Theme = ThemeStyle.Light; welcomePage.Theme = ThemeStyle.Light; debloatPage.Theme = ThemeStyle.Light; + poisonLabel1.Theme = ThemeStyle.Light; + poisonLabel2.Theme = ThemeStyle.Light; + LblInstalledCount.Theme = ThemeStyle.Light; + LblRemoveCount.Theme = ThemeStyle.Light; + LstUWP.Theme = ThemeStyle.Light; + LstUWPRemove.Theme = ThemeStyle.Light; + ChkShowUWPSystem.Theme = ThemeStyle.Light; + BtnRunUninstaller.Theme = ThemeStyle.Light; + addAllButton.Theme = ThemeStyle.Light; + addButton.Theme = ThemeStyle.Light; + removeAllButton.Theme = ThemeStyle.Light; + removeButton.Theme = ThemeStyle.Light; + welcomePage.BackgroundImage = Resources.win11wallpaperlight; + tweaksPage.Theme = ThemeStyle.Light; + tweaksList.Theme = ThemeStyle.Light; + runTweaks.Theme = ThemeStyle.Light; + editionLabel.Theme = ThemeStyle.Light; } } private void Form1_Load(object sender, EventArgs e) { - + pages.SelectedTab = welcomePage; // Always start from the first tab + editionLabel.Text = AppEdition; + theme.Text = AppEdition; } private void GetUWP() { LstUWP.Items.Clear(); - - // Run PowerShell to get UWP app names string output = PowerShell.Execute("Get-AppxPackage -allusers | Select-Object -ExpandProperty Name"); - - // Split output into lines string[] lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string line in lines) { string current = line.Trim(); @@ -122,7 +141,7 @@ namespace Perfect11 } private void GetUWPSystem() { - _listSystemApps.Clear(); // Optional: clear old entries + _listSystemApps.Clear(); using (StringReader reader = new StringReader(Resources.UWPSystemAppList)) { @@ -139,19 +158,20 @@ namespace Perfect11 string success = "Successfully removed:" + "\n"; string failed = "Failed to remove:" + "\n"; - foreach (var item in LstUWPRemove.Items) + foreach (ListViewItem item in LstUWPRemove.Items) { - string appName = item.ToString(); - - // Build the command + string appName = item.Text; string command = $"Get-AppxPackage -allusers -Name \"{appName}\" | Remove-AppxPackage -allusers"; - + string command2 = $"Get-AppxProvisionedPackage -online | Where PackageName -like *\"{appName}\"* | Remove-AppxProvisionedPackage -online"; try { + string output2 = PowerShell.Execute(command2); string output = PowerShell.Execute(command); - - // Basic success/failure logic (you can enhance this) - if (!string.IsNullOrWhiteSpace(output) && !output.ToLower().Contains("error")) +#if DEBUG + MessageBox.Show(output2); + MessageBox.Show(output); +#endif + if (!output.ToLower().Contains("error") && !output2.ToLower().Contains("error")) { success += "\t" + appName + "\n"; } @@ -165,8 +185,6 @@ namespace Perfect11 failed += $"\t{appName} ({ex.Message})\n"; } } - - // Return status summary return success + (failed != "Failed to remove:" + "\n" ? "\n" + failed : ""); } @@ -181,7 +199,7 @@ namespace Perfect11 var itemsToMove = LstUWP.Items.Cast().ToList(); foreach (var item in itemsToMove) { - LstUWPRemove.Items.Add((ListViewItem)item.Clone()); // Clone to avoid reference issues + LstUWPRemove.Items.Add((ListViewItem)item.Clone()); } LstUWP.Items.Clear(); RefreshUWP(); @@ -202,7 +220,6 @@ namespace Perfect11 { if (LstUWPRemove.SelectedItems.Count > 0) { - // Create a temporary list to avoid modifying collection during iteration List selectedItems = new List(); foreach (ListViewItem selectedItem in LstUWPRemove.SelectedItems) @@ -223,21 +240,13 @@ namespace Perfect11 private void removeAllButton_Click(object sender, EventArgs e) { - // Create a temporary list to hold items to move List itemsToMove = new List(); - foreach (ListViewItem item in LstUWPRemove.Items) { - // Clone the item to add to the other ListView itemsToMove.Add((ListViewItem)item.Clone()); } - - // Add to destination ListView LstUWP.Items.AddRange(itemsToMove.ToArray()); - - // Clear source ListView LstUWPRemove.Items.Clear(); - RefreshUWP(); } @@ -247,13 +256,89 @@ namespace Perfect11 else { Enabled = false; - - MessageBox.Show(RemoveUWP()); - + MessageBox.Show(RemoveUWP(),"Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information); LstUWPRemove.Items.Clear(); GetUWP(); Enabled = true; } } + private void InitializeTweaks() + { + if (!Directory.Exists("Tweaks")) + { + Directory.CreateDirectory("Tweaks"); + } + if (File.Exists("Tweaks\\Perfect11.TweaksInterface.dll")) + { + File.Delete("Tweaks\\Perfect11.TweaksInterface.dll"); + } + tweaksList.View = View.Details; + tweaksList.Columns.Add("Name", 150); + tweaksList.Columns.Add("Description", 300); + tweaksList.FullRowSelect = true; + int totalWidth = tweaksList.ClientSize.Width; + tweaksList.Columns[0].Width = (int)(totalWidth * 0.4); + tweaksList.Columns[1].Width = (int)(totalWidth * 0.6); + + // Load plugins + _tweaks = Utilities.LoadTweaks("Tweaks"); + + // Populate ListView + foreach (var plugin in _tweaks) + { + var item = new ListViewItem(plugin.Name); + item.SubItems.Add(plugin.Description); + item.Tag = plugin; // store the plugin object for later + tweaksList.Items.Add(item); + } + if (tweaksList.Items.Count == 0) runTweaks.Enabled = false; + } + private void InitializeDarkMode() + { + if (Utilities.IsAppsDarkMode()) + { + DarkMode(true); + } + else + { + DarkMode(false); + } + } + + private async void runTweaks_Click(object sender, EventArgs e) + { + if (tweaksList.SelectedItems.Count == 0) + { + MessageBox.Show("Select one or more plugins to run.","Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information); + return; + } + + Enabled = false; // prevent multiple clicks + try + { + foreach (ListViewItem item in tweaksList.SelectedItems) + { + if (item.Tag is IPlugin plugin) + { + await Task.Run(() => plugin.Execute()); // run in background thread + } + } + } + catch (Exception ex) + { + MessageBox.Show($"Error running plugin: {ex.Message}", "Perfect11", MessageBoxButtons.OK,MessageBoxIcon.Error); + } + finally + { + Enabled = true; + } + } + + private void tweaksList_Resize(object sender, EventArgs e) + { + int totalWidth = tweaksList.ClientSize.Width; + tweaksList.Columns[0].Width = (int)(totalWidth * 0.4); + tweaksList.Columns[1].Width = (int)(totalWidth * 0.6); + } } } diff --git a/Perfect11/Library/PowerShell.cs b/Perfect11/Library/PowerShell.cs index dd40917..45a2955 100644 --- a/Perfect11/Library/PowerShell.cs +++ b/Perfect11/Library/PowerShell.cs @@ -1,11 +1,4 @@ -using Microsoft.VisualBasic.ApplicationServices; -using Microsoft.VisualBasic.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics; namespace Perfect11.Library { diff --git a/Perfect11/Library/Utilities.cs b/Perfect11/Library/Utilities.cs index b055fa4..41d8189 100644 --- a/Perfect11/Library/Utilities.cs +++ b/Perfect11/Library/Utilities.cs @@ -1,9 +1,10 @@ -using System; +using Microsoft.Win32; +using Perfect11.TweaksInterface; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Win32; +using System.Reflection; namespace Perfect11.Library { @@ -16,5 +17,34 @@ namespace Perfect11.Library "CurrentBuildNumber", null); return int.TryParse(buildNumber, out int build) && build >= 22000; } + public static List LoadTweaks(string path) + { + var plugins = new List(); + + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + + foreach (var file in Directory.GetFiles(path, "*.dll")) + { + var assembly = Assembly.LoadFrom(file); + var types = assembly.GetTypes() + .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract); + + foreach (var type in types) + { + if (Activator.CreateInstance(type) is IPlugin plugin) + plugins.Add(plugin); + } + } + + return plugins; + } + public static bool IsAppsDarkMode() + { + RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"); + int value = (int)rk.GetValue("AppsUseLightTheme"); + rk.Close(); + return value == 0; + } } } diff --git a/Perfect11/Perfect11.csproj b/Perfect11/Perfect11.csproj index 469c581..6b7e615 100644 --- a/Perfect11/Perfect11.csproj +++ b/Perfect11/Perfect11.csproj @@ -55,6 +55,9 @@ Simpleicons-Team-Simple-Windows-11.ico + + + @@ -131,5 +134,11 @@ + + + {b3f8761a-b4b2-4378-9fe8-06bbfc39fce6} + Perfect11.TweaksInterface + + \ No newline at end of file diff --git a/Perfect11/Program.cs b/Perfect11/Program.cs index 248f711..3358dcc 100644 --- a/Perfect11/Program.cs +++ b/Perfect11/Program.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; using Perfect11.Library; diff --git a/Perfect11/Resources/UWPSystemAppList.txt b/Perfect11/Resources/UWPSystemAppList.txt index 0cf9dae..c1a6c9b 100644 --- a/Perfect11/Resources/UWPSystemAppList.txt +++ b/Perfect11/Resources/UWPSystemAppList.txt @@ -56,4 +56,17 @@ NcsiUwpApp Microsoft.DesktopAppInstaller Microsoft.SecHealthUI Microsoft.StartExperiencesApp -Microsoft.Windows.AugLoop.CBS \ No newline at end of file +Microsoft.Windows.AugLoop.CBS +MicrosoftWindows.Client.AIX +MicrosoftWindows.Client.CBS +MicrosoftWindows.Client.Core +MicrosoftWindows.Client.FileExp +MicrosoftWindows.Client.OOBE +MicrosoftWindows.Client.Photon +MicrosoftWindows.Client.WebExperience +MicrosoftWindows.CrossDevice +MicrosoftWindows.UndockedDevKit +Microsoft.LanguageExperiencePack +Microsoft.XboxIdentityProvider +Microsoft.Xbox.TCUI +Microsoft.Edge.GameAssist \ No newline at end of file diff --git a/tweaks/Perfect11.Inbox.UninstallOneDrive/Perfect11.Inbox.UninstallOneDrive.csproj b/tweaks/Perfect11.Inbox.UninstallOneDrive/Perfect11.Inbox.UninstallOneDrive.csproj new file mode 100644 index 0000000..8ae360b --- /dev/null +++ b/tweaks/Perfect11.Inbox.UninstallOneDrive/Perfect11.Inbox.UninstallOneDrive.csproj @@ -0,0 +1,55 @@ + + + + + Debug + AnyCPU + {AD55727D-A52C-459D-A316-3459AA80050A} + Library + Properties + Perfect11.Inbox.UninstallOneDrive + Perfect11.Inbox.UninstallOneDrive + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + none + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + {b3f8761a-b4b2-4378-9fe8-06bbfc39fce6} + Perfect11.TweaksInterface + False + + + + \ No newline at end of file diff --git a/tweaks/Perfect11.Inbox.UninstallOneDrive/Properties/AssemblyInfo.cs b/tweaks/Perfect11.Inbox.UninstallOneDrive/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..006b8ba --- /dev/null +++ b/tweaks/Perfect11.Inbox.UninstallOneDrive/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Perfect11 Inbox Plugins")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Vichingo455")] +[assembly: AssemblyProduct("Perfect11")] +[assembly: AssemblyCopyright("Copyright © 2025 Vichingo455")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ad55727d-a52c-459d-a316-3459aa80050a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tweaks/Perfect11.Inbox.UninstallOneDrive/Tweak.cs b/tweaks/Perfect11.Inbox.UninstallOneDrive/Tweak.cs new file mode 100644 index 0000000..85647ef --- /dev/null +++ b/tweaks/Perfect11.Inbox.UninstallOneDrive/Tweak.cs @@ -0,0 +1,172 @@ +using Microsoft.Win32; +using Perfect11.TweaksInterface; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perfect11.Inbox.UninstallOneDrive +{ + public class Tweak : IPlugin + { + public string Name => "Uninstall OneDrive"; + public string Description => "Remove OneDrive from the system."; + public void Execute() + { + // --- Step 0: Check if OneDrive exists --- + bool Exists() + { + bool regExists = false; + try + { + using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")) + { + if (key != null) + regExists = key.GetSubKeyNames().Any(n => n.ToLower().Contains("onedrive")); + } + } + catch { } + + return regExists; + } + + if (!Exists()) + { + throw new Exception("OneDrive not found, cannot continue!"); + } + // --- Step 1: Check if OneDrive folders contain files --- + string usersRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 3), "Users"); + foreach (var dir in Directory.GetDirectories(usersRoot)) + { + string oneDrivePath = Path.Combine(dir, "OneDrive"); + if (Directory.Exists(oneDrivePath) && Directory.EnumerateFileSystemEntries(oneDrivePath).Any()) + { + throw new Exception("OneDrive files found, cannot continue!"); + } + } + + // --- Step 2: Kill OneDrive process --- + foreach (var proc in Process.GetProcessesByName("OneDrive")) + try { proc.Kill(); } catch { } + + // --- Step 3: Uninstall OneDrive executables --- + foreach (string setupPath in new[] + { + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32", "OneDriveSetup.exe"), + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64", "OneDriveSetup.exe") + }) + { + if (File.Exists(setupPath)) + { + Process.Start(new ProcessStartInfo + { + FileName = setupPath, + Arguments = "/uninstall", + CreateNoWindow = true, + UseShellExecute = false + })?.WaitForExit(5000); + } + } + + // --- Step 4: Remove folders --- + void TryDelete(string path, bool isDir) + { + try + { + if (isDir && Directory.Exists(path)) Directory.Delete(path, true); + else if (!isDir && File.Exists(path)) File.Delete(path); + } + catch { } + } + + TryDelete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Microsoft", "OneDrive"), true); + TryDelete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "OneDrive"), true); + + foreach (var dir in Directory.GetDirectories(usersRoot)) + { + TryDelete(Path.Combine(dir, "AppData", "Local", "Microsoft", "OneDrive"), true); + TryDelete(Path.Combine(dir, "OneDrive"), true); + TryDelete(Path.Combine(dir, "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "OneDrive.lnk"), false); + } + + // --- Step 5: Clean registry (HKLM + HKU) --- + try + { + using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager", true)) + { + if (key != null) + { + foreach (var sub in key.GetSubKeyNames().Where(k => k.Contains("OneDrive")).ToArray()) + key.DeleteSubKeyTree(sub, false); + } + } + } + catch { } + + foreach (string userHive in Registry.Users.GetSubKeyNames()) + { + if (!userHive.StartsWith("S-")) continue; + + string[] paths = + { + @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BannerStore", + @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\Handlers", + @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", + @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" + }; + + foreach (string p in paths) + { + try + { + using (var key = Registry.Users.OpenSubKey($"{userHive}\\{p}", true)) + { + if (key == null) continue; + foreach (var sub in key.GetSubKeyNames().Where(n => n.Contains("OneDrive")).ToArray()) + key.DeleteSubKeyTree(sub, false); + } + } + catch { } + } + + try + { + Registry.SetValue($@"HKEY_USERS\{userHive}\SOFTWARE\Classes\CLSID\{{018D5C66-4533-4307-9B53-224DE2ED1FE6}}", "System.IsPinnedToNameSpaceTree", 0, RegistryValueKind.DWord); + Registry.SetValue($@"HKEY_USERS\{userHive}\SOFTWARE\Classes\WOW6432Node\CLSID\{{018D5C66-4533-4307-9B53-224DE2ED1FE6}}", "System.IsPinnedToNameSpaceTree", 0, RegistryValueKind.DWord); + Registry.Users.DeleteSubKeyTree($"{userHive}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\{{018D5C66-4533-4307-9B53-224DE2ED1FE6}}", false); + + using (var env = Registry.Users.OpenSubKey(userHive + "\\Environment", true)) + env?.DeleteValue("OneDrive", false); + + using (var run = Registry.Users.OpenSubKey(userHive + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true)) + run?.DeleteValue("OneDriveSetup", false); + } + catch { } + } + + // --- Step 6: Remove scheduled tasks --- + void DeleteTask(string name) + { + try + { + Process.Start(new ProcessStartInfo + { + FileName = "schtasks", + Arguments = $"/delete /tn \"{name}\" /f", + CreateNoWindow = true, + UseShellExecute = false + }); + } + catch { } + } + + DeleteTask(@"\OneDrive Reporting Task"); + DeleteTask(@"\OneDrive Standalone Update Task"); + + Console.WriteLine("OneDrive has been completely removed."); + } + } +}