Push 0.50-stable

This commit is contained in:
Belim
2025-05-07 16:11:41 +02:00
parent 2eb417d538
commit 2163abd06f
11 changed files with 1474 additions and 41 deletions
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34928.147
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSCFixer", "MSCFixer\MSCFixer.csproj", "{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2071364D-7643-47BA-922C-79B33CCDCCA1}
EndGlobalSection
EndGlobal
+82 -2
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -40,7 +41,37 @@ namespace Crapfixer
Logger.Log($"(Checked against {_appDirectory.Count} apps from the system)");
}
// Aanalyzes the apps based on predefined apps (from resources) and returns matching apps
/// <summary>
/// Analyzes the apps based on predefined apps (from resources) and logs the results in MainForm.
/// </summary>
/// <param name="predefinedApps"></param>
/// <returns></returns>
public async Task<List<AppAnalysisResult>> AnalyzeAndLogAppsAsync(string[] predefinedApps)
{
var apps = await AnalyzeAppsAsync(predefinedApps);
if (apps.Count > 0)
{
Logger.Log("Bloatware apps detected:", LogLevel.Info);
foreach (var app in apps)
{
Logger.Log($"❌ {app.AppName} [{app.FullName}]", LogLevel.Warning);
}
}
else
{
Logger.Log("✅ No Microsoft Store bloatware apps found.", LogLevel.Info);
}
return apps;
}
/// <summary>
/// Analyzes the apps based on predefined apps (from resources) and returns matching apps.
/// </summary>
/// <param name="predefinedApps"></param>
/// <returns></returns>
public async Task<List<AppAnalysisResult>> AnalyzeAppsAsync(string[] predefinedApps)
{
Logger.Log("\n🧩 APPS ANALYSIS", LogLevel.Info);
@@ -100,7 +131,11 @@ namespace Crapfixer
}
}
// Uninstall selected apps and log the results
/// <summary>
/// Uninstalls the selected apps and logs the results.
/// </summary>
/// <param name="selectedApps"></param>
/// <returns></returns>
public async Task<List<string>> UninstallSelectedAppsAsync(List<string> selectedApps)
{
List<string> removedApps = new List<string>();
@@ -134,5 +169,50 @@ namespace Crapfixer
return removedApps; // Return removed apps to update the UI
}
/// <summary>
/// Loads an external bloatware list from the CFEnhancer text file (comma-separated).
/// Falls back to an empty array if the file doesn't exist or fails to load.
/// </summary>
public string[] LoadExternalBloatwareList(string fileName = "CFEnhancer.txt")
{
try
{
string exeDir = AppDomain.CurrentDomain.BaseDirectory;
string fullPath = Path.Combine(exeDir, fileName);
if (!File.Exists(fullPath))
{
Logger.Log($"⚠️ The bloatware radar stays basic for now 🧠. Get the enhanced detection list from the GitHub releases (Assets).", LogLevel.Warning);
return Array.Empty<string>();
}
var content = File.ReadAllText(fullPath);
return content.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim())
.ToArray();
}
catch (Exception ex)
{
Logger.Log($"Error reading external bloatware file: {ex.Message}", LogLevel.Warning);
return Array.Empty<string>();
}
}
/// <summary>
/// OPTIONALLY!Returns all installed apps in the system.
/// </summary>
/// <returns></returns>
public async Task<List<AppAnalysisResult>> GetAllInstalledAppsAsync()
{
await LoadAppsAsync();
return _appDirectory.Select(kvp => new AppAnalysisResult
{
AppName = kvp.Key,
FullName = kvp.Value
}).ToList();
}
}
}
+44 -22
View File
@@ -1,4 +1,5 @@
using Features;
using System;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -123,26 +124,6 @@ namespace Crapfixer
}
}
/// <summary>
/// Analyzes a selected feature and logs its status.
/// </summary>
public static async void AnalyzeFeature(TreeNode node)
{
if (node.Tag is FeatureNode fn && !fn.IsCategory && node.Checked && fn.Feature != null)
{
bool isOk = await fn.Feature.CheckFeature();
node.ForeColor = isOk ? Color.Gray : Color.Red;
Logger.Log(isOk
? $"✅ Feature: {fn.Name} is properly configured."
: $"❌ Feature: {fn.Name} requires attention.\n ➤ {fn.Feature.GetFeatureDetails()}",
isOk ? LogLevel.Info : LogLevel.Warning);
if (!isOk)
Logger.Log(new string('-', 50), LogLevel.Info);
}
}
/// <summary>
/// Fixes all checked features recursively.
/// </summary>
@@ -186,12 +167,36 @@ namespace Crapfixer
}
}
/// <summary>
/// Analyzes a selected feature and logs its status.
/// </summary>
public static async void AnalyzeFeature(TreeNode node)
{
// no && node.Checked
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
bool isOk = await fn.Feature.CheckFeature();
node.ForeColor = isOk ? Color.Gray : Color.Red;
Logger.Log(isOk
? $"✅ Feature: {fn.Name} is properly configured."
: $"❌ Feature: {fn.Name} requires attention.\n ➤ {fn.Feature.GetFeatureDetails()}",
isOk ? LogLevel.Info : LogLevel.Warning);
if (!isOk)
Logger.Log(new string('-', 50), LogLevel.Info);
}
}
/// <summary>
/// Attempts to fix the selected feature and logs the result.
/// </summary>
public static async Task FixFeature(TreeNode node)
{
if (node.Tag is FeatureNode fn && !fn.IsCategory && node.Checked && fn.Feature != null)
// no && node.Checked
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
bool result = await fn.Feature.DoFeature();
Logger.Log(result
@@ -206,7 +211,8 @@ namespace Crapfixer
/// </summary>
public static void RestoreFeature(TreeNode node)
{
if (node.Tag is FeatureNode fn && !fn.IsCategory && node.Checked && fn.Feature != null)
// no && node.Checked
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
bool ok = fn.Feature.UndoFeature();
Logger.Log(ok
@@ -235,5 +241,21 @@ namespace Crapfixer
MessageBox.Show("⚠️ No feature selected or feature is invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Opens the default web browser to search for help online for the selected feature (Extended ShowHelp).
/// </summary>
/// <param name="node"></param>
public static void ShowHelpOnline(TreeNode node)
{
if (node?.Tag is FeatureNode fn)
{
string searchQuery = Uri.EscapeDataString( fn.Feature.GetFeatureDetails());
string webUrl = $"microsoft-edge:https://www.google.com/search?q={searchQuery}";
System.Diagnostics.Process.Start(webUrl);
}
}
}
}
+170
View File
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>MSCFixer</RootNamespace>
<AssemblyName>MSCFixer</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>AppIcon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Windows">
<HintPath>..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AppManagerService.cs" />
<Compile Include="FeatureManager.cs" />
<Compile Include="Features\Edge\BrowserSignin.cs" />
<Compile Include="Features\Edge\DefaultTopSites.cs" />
<Compile Include="Features\Edge\DefautBrowserSetting.cs" />
<Compile Include="Features\Edge\EdgeCollections.cs" />
<Compile Include="Features\Edge\EdgeShoppingAssistant.cs" />
<Compile Include="Features\Edge\FirstRunExperience.cs" />
<Compile Include="Features\Edge\GamerMode.cs" />
<Compile Include="Features\Edge\HubsSidebar.cs" />
<Compile Include="Features\Edge\ImportOnEachLaunch.cs" />
<Compile Include="Features\Edge\StartupBoost.cs" />
<Compile Include="Features\Edge\TabPageQuickLinks.cs" />
<Compile Include="Features\Edge\UserFeedback.cs" />
<Compile Include="Features\Issues\BasicCleanup.cs" />
<Compile Include="Features\Issues\WingetUpgrade.cs" />
<Compile Include="Features\System\MenuShowDelay.cs" />
<Compile Include="Features\System\NetworkThrottling.cs" />
<Compile Include="Features\System\SpeedUpShutdown.cs" />
<Compile Include="Features\System\SystemResponsiveness.cs" />
<Compile Include="Features\UI\DarkMode.cs" />
<Compile Include="Features\UI\SearchBoxSuggestions.cs" />
<Compile Include="Features\UI\SnapAssistFlyout.cs" />
<Compile Include="Features\UI\Transparency.cs" />
<Compile Include="Helpers\OSHelper.cs" />
<Compile Include="Helpers\Utils.cs" />
<Compile Include="Helpers\Logger.cs" />
<Compile Include="IniStateManager.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="NavigationHandler.cs" />
<Compile Include="NavigationManager.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="FeatureBase.cs" />
<Compile Include="FeatureNode.cs" />
<Compile Include="Features\Ads\FileExlorerAds.cs" />
<Compile Include="Features\Ads\FinishSetupAds.cs" />
<Compile Include="Features\Ads\LockScreenAds.cs" />
<Compile Include="Features\Ads\PersonalizedAds.cs" />
<Compile Include="Features\Ads\SettingsAds.cs" />
<Compile Include="Features\Ads\StartmenuAds.cs" />
<Compile Include="Features\Ads\TailoredExperiences.cs" />
<Compile Include="Features\Ads\TipsAndSuggestions.cs" />
<Compile Include="Features\Ads\WelcomeExperienceAds.cs" />
<Compile Include="Features\AI\CopilotTaskbar.cs" />
<Compile Include="Features\AI\Recall.cs" />
<Compile Include="Features\Gaming\GameDVR.cs" />
<Compile Include="Features\Gaming\PowerThrotteling.cs" />
<Compile Include="Features\Gaming\VisualFX.cs" />
<Compile Include="Features\Privacy\ActivityHistory.cs" />
<Compile Include="Features\Privacy\LocationTracking.cs" />
<Compile Include="Features\Privacy\PrivacyExperience.cs" />
<Compile Include="Features\Privacy\Telemetry.cs" />
<Compile Include="Features\System\BSODDetails.cs" />
<Compile Include="Features\System\VerboseStatus.cs" />
<Compile Include="Features\UI\FullContextMenus.cs" />
<Compile Include="Features\UI\LockScreen.cs" />
<Compile Include="Features\UI\SearchboxTaskbarMode.cs" />
<Compile Include="Features\UI\ShowOrHideMostUsedApps.cs" />
<Compile Include="Features\UI\ShowTaskViewButton.cs" />
<Compile Include="Features\UI\StartLayout.cs" />
<Compile Include="Features\UI\TaskbarAlignment.cs" />
<Compile Include="Views\SettingsView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\SettingsView.Designer.cs">
<DependentUpon>SettingsView.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Views\SettingsView.resx">
<DependentUpon>SettingsView.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.manifest" />
<Compile Include="FeatureLoader.cs" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="AppIcon.ico" />
<None Include="AppIcon32.png" />
<None Include="AppIcon.png" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+479
View File
@@ -0,0 +1,479 @@
namespace Crapfixer
{
partial class MainForm
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panelContainer = new System.Windows.Forms.Panel();
this.panelContent = new System.Windows.Forms.Panel();
this.btnAnalyze = new System.Windows.Forms.Button();
this.tabControl = new System.Windows.Forms.TabControl();
this.Windows = new System.Windows.Forms.TabPage();
this.treeFeatures = new System.Windows.Forms.TreeView();
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.analyzeMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fixMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.seperatorToolStripMenuItem = new System.Windows.Forms.ToolStripSeparator();
this.restoreMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.Apps = new System.Windows.Forms.TabPage();
this.checkedListBoxApps = new System.Windows.Forms.CheckedListBox();
this.groupBox = new System.Windows.Forms.GroupBox();
this.rtbLogger = new System.Windows.Forms.RichTextBox();
this.btnFix = new System.Windows.Forms.Button();
this.panelHeader = new System.Windows.Forms.Panel();
this.lblOSInfo = new System.Windows.Forms.Label();
this.lblVersionInfo = new System.Windows.Forms.Label();
this.lblHeader = new System.Windows.Forms.Label();
this.pictureHeader = new System.Windows.Forms.PictureBox();
this.btnRestore = new System.Windows.Forms.Button();
this.linkHelp = new System.Windows.Forms.LinkLabel();
this.btnSettings = new System.Windows.Forms.Button();
this.btnHome = new System.Windows.Forms.Button();
this.linkSelection = new System.Windows.Forms.LinkLabel();
this.panelContainer.SuspendLayout();
this.panelContent.SuspendLayout();
this.tabControl.SuspendLayout();
this.Windows.SuspendLayout();
this.contextMenuStrip.SuspendLayout();
this.Apps.SuspendLayout();
this.groupBox.SuspendLayout();
this.panelHeader.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureHeader)).BeginInit();
this.SuspendLayout();
//
// panelContainer
//
this.panelContainer.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.panelContainer.BackColor = System.Drawing.SystemColors.Control;
this.panelContainer.Controls.Add(this.panelContent);
this.panelContainer.Location = new System.Drawing.Point(99, 62);
this.panelContainer.Name = "panelContainer";
this.panelContainer.Size = new System.Drawing.Size(611, 382);
this.panelContainer.TabIndex = 198;
//
// panelContent
//
this.panelContent.AutoScroll = true;
this.panelContent.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(252)))), ((int)(((byte)(252)))));
this.panelContent.Controls.Add(this.btnAnalyze);
this.panelContent.Controls.Add(this.tabControl);
this.panelContent.Controls.Add(this.groupBox);
this.panelContent.Controls.Add(this.btnFix);
this.panelContent.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelContent.Location = new System.Drawing.Point(0, 0);
this.panelContent.Name = "panelContent";
this.panelContent.Size = new System.Drawing.Size(611, 382);
this.panelContent.TabIndex = 205;
//
// btnAnalyze
//
this.btnAnalyze.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnAnalyze.AutoEllipsis = true;
this.btnAnalyze.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnAnalyze.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnAnalyze.Location = new System.Drawing.Point(280, 346);
this.btnAnalyze.Name = "btnAnalyze";
this.btnAnalyze.Size = new System.Drawing.Size(121, 29);
this.btnAnalyze.TabIndex = 1;
this.btnAnalyze.Text = "&Analyze";
this.btnAnalyze.UseVisualStyleBackColor = false;
this.btnAnalyze.Click += new System.EventHandler(this.btnAnalyze_Click);
//
// tabControl
//
this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.tabControl.Controls.Add(this.Windows);
this.tabControl.Controls.Add(this.Apps);
this.tabControl.HotTrack = true;
this.tabControl.Location = new System.Drawing.Point(0, 0);
this.tabControl.Name = "tabControl";
this.tabControl.Padding = new System.Drawing.Point(20, 8);
this.tabControl.SelectedIndex = 0;
this.tabControl.ShowToolTips = true;
this.tabControl.Size = new System.Drawing.Size(270, 376);
this.tabControl.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
this.tabControl.TabIndex = 199;
//
// Windows
//
this.Windows.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240)))));
this.Windows.Controls.Add(this.treeFeatures);
this.Windows.Location = new System.Drawing.Point(4, 32);
this.Windows.Name = "Windows";
this.Windows.Padding = new System.Windows.Forms.Padding(3);
this.Windows.Size = new System.Drawing.Size(262, 340);
this.Windows.TabIndex = 0;
this.Windows.Text = "Windows";
//
// treeFeatures
//
this.treeFeatures.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.treeFeatures.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.treeFeatures.CheckBoxes = true;
this.treeFeatures.ContextMenuStrip = this.contextMenuStrip;
this.treeFeatures.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeFeatures.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.treeFeatures.Indent = 20;
this.treeFeatures.ItemHeight = 23;
this.treeFeatures.Location = new System.Drawing.Point(3, 3);
this.treeFeatures.Name = "treeFeatures";
this.treeFeatures.ShowLines = false;
this.treeFeatures.ShowNodeToolTips = true;
this.treeFeatures.ShowPlusMinus = false;
this.treeFeatures.ShowRootLines = false;
this.treeFeatures.Size = new System.Drawing.Size(256, 334);
this.treeFeatures.TabIndex = 196;
this.treeFeatures.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeFeatures_AfterCheck);
this.treeFeatures.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeFeatures_MouseDown);
//
// contextMenuStrip
//
this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.analyzeMarkedFeatureToolStripMenuItem,
this.fixMarkedFeatureToolStripMenuItem,
this.seperatorToolStripMenuItem,
this.restoreMarkedFeatureToolStripMenuItem,
this.helpMarkedFeatureToolStripMenuItem});
this.contextMenuStrip.Name = "contextManualMenu";
this.contextMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
this.contextMenuStrip.Size = new System.Drawing.Size(119, 98);
//
// analyzeMarkedFeatureToolStripMenuItem
//
this.analyzeMarkedFeatureToolStripMenuItem.Name = "analyzeMarkedFeatureToolStripMenuItem";
this.analyzeMarkedFeatureToolStripMenuItem.Size = new System.Drawing.Size(118, 22);
this.analyzeMarkedFeatureToolStripMenuItem.Text = "Analyze";
this.analyzeMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.analyzeMarkedFeatureToolStripMenuItem_Click);
//
// fixMarkedFeatureToolStripMenuItem
//
this.fixMarkedFeatureToolStripMenuItem.Name = "fixMarkedFeatureToolStripMenuItem";
this.fixMarkedFeatureToolStripMenuItem.Size = new System.Drawing.Size(118, 22);
this.fixMarkedFeatureToolStripMenuItem.Text = "Fix";
this.fixMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.fixMarkedFeatureToolStripMenuItem_Click);
//
// seperatorToolStripMenuItem
//
this.seperatorToolStripMenuItem.Name = "seperatorToolStripMenuItem";
this.seperatorToolStripMenuItem.Size = new System.Drawing.Size(115, 6);
//
// restoreMarkedFeatureToolStripMenuItem
//
this.restoreMarkedFeatureToolStripMenuItem.Name = "restoreMarkedFeatureToolStripMenuItem";
this.restoreMarkedFeatureToolStripMenuItem.Size = new System.Drawing.Size(118, 22);
this.restoreMarkedFeatureToolStripMenuItem.Text = "Restore";
this.restoreMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.restoreMarkedFeatureToolStripMenuItem_Click);
//
// helpMarkedFeatureToolStripMenuItem
//
this.helpMarkedFeatureToolStripMenuItem.Name = "helpMarkedFeatureToolStripMenuItem";
this.helpMarkedFeatureToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1;
this.helpMarkedFeatureToolStripMenuItem.Size = new System.Drawing.Size(118, 22);
this.helpMarkedFeatureToolStripMenuItem.Text = "Help";
this.helpMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.helpMarkedFeatureToolStripMenuItem_Click);
//
// Apps
//
this.Apps.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.Apps.Controls.Add(this.checkedListBoxApps);
this.Apps.Location = new System.Drawing.Point(4, 32);
this.Apps.Name = "Apps";
this.Apps.Padding = new System.Windows.Forms.Padding(3);
this.Apps.Size = new System.Drawing.Size(262, 340);
this.Apps.TabIndex = 1;
this.Apps.Text = "Apps";
//
// checkedListBoxApps
//
this.checkedListBoxApps.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.checkedListBoxApps.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.checkedListBoxApps.Dock = System.Windows.Forms.DockStyle.Fill;
this.checkedListBoxApps.Font = new System.Drawing.Font("Tahoma", 8F);
this.checkedListBoxApps.FormattingEnabled = true;
this.checkedListBoxApps.Items.AddRange(new object[] {
"No analysis yet"});
this.checkedListBoxApps.Location = new System.Drawing.Point(3, 3);
this.checkedListBoxApps.Name = "checkedListBoxApps";
this.checkedListBoxApps.Size = new System.Drawing.Size(256, 334);
this.checkedListBoxApps.Sorted = true;
this.checkedListBoxApps.TabIndex = 336;
this.checkedListBoxApps.ThreeDCheckBoxes = true;
//
// groupBox
//
this.groupBox.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.groupBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(252)))), ((int)(((byte)(252)))));
this.groupBox.Controls.Add(this.rtbLogger);
this.groupBox.Location = new System.Drawing.Point(280, 21);
this.groupBox.Name = "groupBox";
this.groupBox.Size = new System.Drawing.Size(320, 317);
this.groupBox.TabIndex = 200;
this.groupBox.TabStop = false;
//
// rtbLogger
//
this.rtbLogger.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.rtbLogger.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(252)))), ((int)(((byte)(252)))));
this.rtbLogger.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.rtbLogger.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.rtbLogger.Location = new System.Drawing.Point(7, 12);
this.rtbLogger.Name = "rtbLogger";
this.rtbLogger.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
this.rtbLogger.Size = new System.Drawing.Size(305, 297);
this.rtbLogger.TabIndex = 195;
this.rtbLogger.Text = "";
//
// btnFix
//
this.btnFix.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnFix.AutoEllipsis = true;
this.btnFix.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnFix.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnFix.Location = new System.Drawing.Point(480, 346);
this.btnFix.Name = "btnFix";
this.btnFix.Size = new System.Drawing.Size(121, 29);
this.btnFix.TabIndex = 2;
this.btnFix.Text = "Run &CFixer";
this.btnFix.UseVisualStyleBackColor = false;
this.btnFix.Click += new System.EventHandler(this.btnFix_Click);
//
// panelHeader
//
this.panelHeader.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(77)))), ((int)(((byte)(77)))));
this.panelHeader.Controls.Add(this.lblOSInfo);
this.panelHeader.Controls.Add(this.lblVersionInfo);
this.panelHeader.Controls.Add(this.lblHeader);
this.panelHeader.Controls.Add(this.pictureHeader);
this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.panelHeader.Location = new System.Drawing.Point(0, 0);
this.panelHeader.Name = "panelHeader";
this.panelHeader.Size = new System.Drawing.Size(710, 61);
this.panelHeader.TabIndex = 204;
this.panelHeader.Paint += new System.Windows.Forms.PaintEventHandler(this.panelHeader_Paint);
//
// lblOSInfo
//
this.lblOSInfo.AutoSize = true;
this.lblOSInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
this.lblOSInfo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.lblOSInfo.Location = new System.Drawing.Point(90, 37);
this.lblOSInfo.Name = "lblOSInfo";
this.lblOSInfo.Size = new System.Drawing.Size(116, 13);
this.lblOSInfo.TabIndex = 200;
this.lblOSInfo.Text = "Checking your system..";
//
// lblVersionInfo
//
this.lblVersionInfo.AutoSize = true;
this.lblVersionInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.5F);
this.lblVersionInfo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.lblVersionInfo.Location = new System.Drawing.Point(195, 15);
this.lblVersionInfo.Name = "lblVersionInfo";
this.lblVersionInfo.Size = new System.Drawing.Size(13, 13);
this.lblVersionInfo.TabIndex = 2;
this.lblVersionInfo.Text = "v";
//
// lblHeader
//
this.lblHeader.AutoEllipsis = true;
this.lblHeader.Font = new System.Drawing.Font("Tahoma", 15F, System.Drawing.FontStyle.Bold);
this.lblHeader.ForeColor = System.Drawing.Color.White;
this.lblHeader.Location = new System.Drawing.Point(89, 9);
this.lblHeader.Name = "lblHeader";
this.lblHeader.Size = new System.Drawing.Size(105, 25);
this.lblHeader.TabIndex = 1;
this.lblHeader.Text = "Crapfixer";
this.lblHeader.UseCompatibleTextRendering = true;
//
// pictureHeader
//
this.pictureHeader.Image = global::MSCFixer.Properties.Resources.AppIcon32;
this.pictureHeader.Location = new System.Drawing.Point(30, 9);
this.pictureHeader.Name = "pictureHeader";
this.pictureHeader.Size = new System.Drawing.Size(44, 41);
this.pictureHeader.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureHeader.TabIndex = 0;
this.pictureHeader.TabStop = false;
//
// btnRestore
//
this.btnRestore.AutoEllipsis = true;
this.btnRestore.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnRestore.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(114)))), ((int)(((byte)(114)))));
this.btnRestore.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnRestore.Font = new System.Drawing.Font("Tahoma", 8.25F);
this.btnRestore.ForeColor = System.Drawing.Color.White;
this.btnRestore.Location = new System.Drawing.Point(0, 129);
this.btnRestore.Name = "btnRestore";
this.btnRestore.Size = new System.Drawing.Size(99, 69);
this.btnRestore.TabIndex = 198;
this.btnRestore.TabStop = false;
this.btnRestore.Text = "&Restore";
this.btnRestore.UseVisualStyleBackColor = true;
this.btnRestore.Click += new System.EventHandler(this.btnRestore_Click);
//
// linkHelp
//
this.linkHelp.ActiveLinkColor = System.Drawing.Color.Blue;
this.linkHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.linkHelp.AutoEllipsis = true;
this.linkHelp.AutoSize = true;
this.linkHelp.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.linkHelp.LinkColor = System.Drawing.Color.White;
this.linkHelp.Location = new System.Drawing.Point(620, 447);
this.linkHelp.Name = "linkHelp";
this.linkHelp.Size = new System.Drawing.Size(63, 13);
this.linkHelp.TabIndex = 203;
this.linkHelp.TabStop = true;
this.linkHelp.Text = "GitHub Help";
this.linkHelp.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btnSettings
//
this.btnSettings.AutoEllipsis = true;
this.btnSettings.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnSettings.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(114)))), ((int)(((byte)(114)))));
this.btnSettings.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnSettings.Font = new System.Drawing.Font("Tahoma", 8.25F);
this.btnSettings.ForeColor = System.Drawing.Color.White;
this.btnSettings.Location = new System.Drawing.Point(0, 197);
this.btnSettings.Name = "btnSettings";
this.btnSettings.Size = new System.Drawing.Size(99, 69);
this.btnSettings.TabIndex = 205;
this.btnSettings.TabStop = false;
this.btnSettings.Text = "&Options";
this.btnSettings.UseVisualStyleBackColor = true;
//
// btnHome
//
this.btnHome.AutoEllipsis = true;
this.btnHome.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(145)))), ((int)(((byte)(235)))));
this.btnHome.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnHome.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(131)))), ((int)(((byte)(222)))));
this.btnHome.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnHome.Font = new System.Drawing.Font("Tahoma", 8.25F);
this.btnHome.ForeColor = System.Drawing.Color.White;
this.btnHome.Location = new System.Drawing.Point(0, 61);
this.btnHome.Name = "btnHome";
this.btnHome.Size = new System.Drawing.Size(99, 69);
this.btnHome.TabIndex = 206;
this.btnHome.TabStop = false;
this.btnHome.Text = "&Home";
this.btnHome.UseVisualStyleBackColor = false;
//
// linkSelection
//
this.linkSelection.ActiveLinkColor = System.Drawing.Color.Blue;
this.linkSelection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.linkSelection.AutoEllipsis = true;
this.linkSelection.AutoSize = true;
this.linkSelection.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.linkSelection.LinkColor = System.Drawing.Color.White;
this.linkSelection.Location = new System.Drawing.Point(10, 447);
this.linkSelection.Name = "linkSelection";
this.linkSelection.Size = new System.Drawing.Size(49, 13);
this.linkSelection.TabIndex = 207;
this.linkSelection.TabStop = true;
this.linkSelection.Text = "Select all";
this.linkSelection.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.linkSelection.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkSelection_LinkClicked);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(104)))), ((int)(((byte)(104)))), ((int)(((byte)(104)))));
this.ClientSize = new System.Drawing.Size(710, 466);
this.Controls.Add(this.linkSelection);
this.Controls.Add(this.btnHome);
this.Controls.Add(this.btnSettings);
this.Controls.Add(this.panelHeader);
this.Controls.Add(this.btnRestore);
this.Controls.Add(this.linkHelp);
this.Controls.Add(this.panelContainer);
this.Name = "MainForm";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Crapfixer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Shown += new System.EventHandler(this.MainForm_Shown);
this.panelContainer.ResumeLayout(false);
this.panelContent.ResumeLayout(false);
this.tabControl.ResumeLayout(false);
this.Windows.ResumeLayout(false);
this.contextMenuStrip.ResumeLayout(false);
this.Apps.ResumeLayout(false);
this.groupBox.ResumeLayout(false);
this.panelHeader.ResumeLayout(false);
this.panelHeader.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureHeader)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
private System.Windows.Forms.ToolStripMenuItem fixMarkedFeatureToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem analyzeMarkedFeatureToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem restoreMarkedFeatureToolStripMenuItem;
private System.Windows.Forms.Panel panelContainer;
private System.Windows.Forms.TabControl tabControl;
private System.Windows.Forms.TabPage Windows;
private System.Windows.Forms.TabPage Apps;
private System.Windows.Forms.GroupBox groupBox;
public System.Windows.Forms.RichTextBox rtbLogger;
private System.Windows.Forms.Button btnFix;
private System.Windows.Forms.Panel panelHeader;
private System.Windows.Forms.PictureBox pictureHeader;
private System.Windows.Forms.Label lblVersionInfo;
private System.Windows.Forms.Label lblHeader;
private System.Windows.Forms.Button btnAnalyze;
private System.Windows.Forms.Button btnRestore;
private System.Windows.Forms.CheckedListBox checkedListBoxApps;
private System.Windows.Forms.ToolStripSeparator seperatorToolStripMenuItem;
private System.Windows.Forms.Panel panelContent;
private System.Windows.Forms.LinkLabel linkHelp;
private System.Windows.Forms.ToolStripMenuItem helpMarkedFeatureToolStripMenuItem;
private System.Windows.Forms.TreeView treeFeatures;
private System.Windows.Forms.Label lblOSInfo;
private System.Windows.Forms.Button btnSettings;
private System.Windows.Forms.Button btnHome;
private System.Windows.Forms.LinkLabel linkSelection;
}
}
+322
View File
@@ -0,0 +1,322 @@
using MSCFixer;
using MSCFixer.Properties;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Views;
namespace Crapfixer
{
public partial class MainForm : Form
{
private NavigationManager navigationManager;
private NavigationHandler navigationHandler;
private readonly AppManagerService appManager = new AppManagerService();
private readonly string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Crapfixer.ini");
public MainForm()
{
InitializeComponent();
navigationManager = new NavigationManager(panelContainer);
Logger.OutputBox = rtbLogger;
FeatureNodeManager.LoadFeatures(treeFeatures);
PluginManager.LoadPlugins(treeFeatures);
}
private void MainForm_Shown(object sender, EventArgs e)
{
InitializeUI();
IniStateManager.Load(treeFeatures, iniPath);
}
private void InitializeUI()
{
navigationHandler = new NavigationHandler(btnHome, btnRestore, btnSettings);
btnHome.Click += (s, e) =>
{
navigationManager.GoToMain();
navigationHandler.SetActive(btnHome);
};
btnRestore.Click += (s, e) =>
{
navigationHandler.SetActive(btnRestore);
};
btnSettings.Click += (s, e) =>
{
navigationManager.SwitchView(new SettingsView(navigationManager));
navigationHandler.SetActive(btnSettings);
};
linkHelp.Click += (s, e) =>
{
Process.Start("https://github.com/builtbybel/Crapfixer/issues");
};
UpdateTitleWithOSVersion(); // Update OS version label
this.lblVersionInfo.Text = $"v{Program.GetCurrentVersionTostring()} "; // Update version label
}
private async void UpdateTitleWithOSVersion()
{
string osVersion = await OSHelper.OSHelper.GetWindowsVersion();
this.lblOSInfo.Text = osVersion;
}
private async void btnAnalyze_Click(object sender, EventArgs e)
{
rtbLogger.Clear();
// Analyze features
await FeatureNodeManager.AnalyzeAll(treeFeatures.Nodes);
// Analyze plugins
foreach (TreeNode node in treeFeatures.Nodes)
{
PluginManager.AnalyzeAll(node);
}
// Analyze apps
await AnalyzeApps();
}
/// <summary>
/// Analyzes the apps and logs the results.
/// </summary>
/// <returns></returns>
private async Task AnalyzeApps()
{
checkedListBoxApps.Items.Clear();
// Try loading external bloatware list from file
string[] predefined = appManager.LoadExternalBloatwareList();
if (predefined.Length == 0)
{
// Fallback to internal resource if external file not found or empty
predefined = Resources.PredefinedApps?
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim()).ToArray() ?? Array.Empty<string>();
// Logger.Log("Using built-in bloatware list.", LogLevel.Info);
}
else
{
Logger.Log("Using external bloatware list via CFEnhancer", LogLevel.Info);
}
// Analyze installed apps against the predefined list
var apps = await appManager.AnalyzeAndLogAppsAsync(predefined);
foreach (var app in apps)
{
checkedListBoxApps.Items.Add(app.FullName);
}
if (!apps.Any())
{
Logger.Log("✅ No bloatware apps found.", LogLevel.Info);
}
}
private async void btnFix_Click(object sender, EventArgs e)
{
rtbLogger.Clear();
// Fix all features
foreach (TreeNode node in treeFeatures.Nodes)
await FeatureNodeManager.FixChecked(node);
// Fix all plugins
foreach (TreeNode node in treeFeatures.Nodes)
await PluginManager.FixChecked(node);
// Fix selected Store apps
var selectedApps = checkedListBoxApps.CheckedItems.Cast<string>().ToList();
if (selectedApps.Count == 0)
return;
var appService = new AppManagerService();
var removedApps = await appService.UninstallSelectedAppsAsync(selectedApps);
// Update UI after uninstall
foreach (var app in removedApps)
{
checkedListBoxApps.Items.Remove(app);
}
}
private void btnRestore_Click(object sender, EventArgs e)
{
var result = MessageBox.Show(
"⚠️ This will restore all selected features to their original state.\n" +
"Changes made by previous configurations may be reverted.\n\n" +
"Are you sure you want to proceed?",
"Restore Selected Features",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
rtbLogger.Clear();
foreach (TreeNode node in treeFeatures.Nodes)
FeatureNodeManager.RestoreChecked(node);
Logger.Log("↩️ All selected features have been restored.", LogLevel.Info);
}
}
private async void analyzeMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
if (PluginManager.IsPluginNode(selectedNode))
await PluginManager.AnalyzePlugin(selectedNode);
else
Logger.Log($"🔎 Analyzing Feature: {selectedNode.Text}", LogLevel.Info);
FeatureNodeManager.AnalyzeFeature(selectedNode);
}
}
private async void fixMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
if (PluginManager.IsPluginNode(selectedNode))
await PluginManager.FixPlugin(selectedNode);
else
Logger.Log($"🔧 Fixing Feature: {selectedNode.Text}", LogLevel.Info);
await FeatureNodeManager.FixFeature(selectedNode);
}
}
private void restoreMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
if (PluginManager.IsPluginNode(selectedNode))
PluginManager.RestorePlugin(selectedNode);
else
Logger.Log($"↩️ Restoring Feature: {selectedNode.Text}", LogLevel.Info);
FeatureNodeManager.RestoreFeature(selectedNode);
}
}
private void helpMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
FeatureNodeManager.ShowHelp(selectedNode);
// Prompt for online search
var result = MessageBox.Show(
"Would you like to search online for more information about this feature?",
"Online Help",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
FeatureNodeManager.ShowHelpOnline(selectedNode);
}
}
}
/// <summary>
/// Checks or unchecks all child nodes when a parent node is checked/unchecked.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treeFeatures_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action != TreeViewAction.Unknown)
{
foreach (TreeNode child in e.Node.Nodes)
child.Checked = e.Node.Checked;
}
}
private void treeFeatures_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
// Get the node under the mouse cursor
TreeNode nodeUnderMouse = treeFeatures.GetNodeAt(e.X, e.Y);
if (nodeUnderMouse != null)
{
treeFeatures.SelectedNode = nodeUnderMouse;
// Show the context menu at the mouse position
contextMenuStrip.Show(treeFeatures, e.Location);
}
}
}
/// <summary>
/// Handles the link click event for selecting or deselecting all items in the list.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private bool treeChecked = false;
private void linkSelection_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (tabControl.SelectedTab == Windows)
{
foreach (TreeNode node in treeFeatures.Nodes)
{
node.Checked = treeChecked;
foreach (TreeNode child in node.Nodes)
{
child.Checked = treeChecked;
foreach (TreeNode grandChild in child.Nodes)
grandChild.Checked = treeChecked;
}
}
treeChecked = !treeChecked;
}
else if (tabControl.SelectedTab == Apps)
{
bool shouldCheck = checkedListBoxApps.Items.Cast<object>()
.Any(item => checkedListBoxApps.GetItemChecked(checkedListBoxApps.Items.IndexOf(item)) == false);
for (int i = 0; i < checkedListBoxApps.Items.Count; i++)
{
checkedListBoxApps.SetItemChecked(i, shouldCheck);
}
}
}
private void panelHeader_Paint(object sender, PaintEventArgs e)
{
Panel panel = sender as Panel;
Graphics g = e.Graphics;
// Fill background
g.Clear(Color.FromArgb(77, 77, 77));
// Draw a single magenta line at the bottom
using (Pen pen = new Pen(Color.FromArgb(100, 255, 0, 255))) // Magenta with transparency
{
int y = panel.Height - 1; // Bottom-most pixel
g.DrawLine(pen, 0, y, panel.Width, y);
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
IniStateManager.Save(treeFeatures, iniPath);
}
}
}
+123
View File
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>23, 15</value>
</metadata>
</root>
+198
View File
@@ -0,0 +1,198 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
public static class PluginManager
{
public static async Task ExecutePlugin(string pluginPath)
{
try
{
using (var process = new Process())
{
process.StartInfo.FileName = "powershell.exe";
process.StartInfo.Arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"{pluginPath}\"";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
process.OutputDataReceived += (s, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
Logger.Log($"[PS Output] {e.Data}");
};
process.ErrorDataReceived += (s, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
Logger.Log($"[PS Error] {e.Data}", LogLevel.Error);
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await Task.Run(() => process.WaitForExit());
Logger.Log($"✅ Script executed: {Path.GetFileName(pluginPath)}");
}
}
catch (Exception ex)
{
Logger.Log($"❌ Error executing script: {ex.Message}", LogLevel.Error);
}
}
public static void LoadPlugins(TreeView treeView)
{
string pluginsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
if (!Directory.Exists(pluginsFolder))
{
Directory.CreateDirectory(pluginsFolder);
// Logger.Log("No Plugins found.\nGet it on https://github.com/builtbybel/Crapfixer");
return;
}
var pluginsNode = new TreeNode("Plugins")
{
// NodeFont = new Font(treeView.Font, FontStyle.Bold),
BackColor = Color.Magenta,
ForeColor = Color.White
};
foreach (var scriptPath in Directory.GetFiles(pluginsFolder, "*.ps1"))
{
var scriptName = Path.GetFileNameWithoutExtension(scriptPath);
var scriptNode = new TreeNode
{
Text = $"{scriptName} [PS]",
ToolTipText = scriptPath,
Tag = scriptPath,
Checked = false
};
pluginsNode.Nodes.Add(scriptNode);
}
treeView.Nodes.Add(pluginsNode);
treeView.ExpandAll(); // expand all nodes
}
public static void AnalyzeAll(TreeNode node)
{
if (node.Tag is string path && node.Checked)
{
Logger.Log($"🔎 Plugin ready: {Path.GetFileName(path)}");
}
foreach (TreeNode child in node.Nodes)
AnalyzeAll(child);
}
/// <summary>
/// Executes all checked plugins in the tree view.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static async Task FixChecked(TreeNode node)
{
if (node.Checked)
{
// Show a warning for each checked plugin
if (node.Tag is string pluginPath)
{
var pluginName = Path.GetFileName(pluginPath); // get the plugin name
var proceed = ShowPluginWarning(pluginName); // the warning message box
if (!proceed) return; // If user chooses not to proceed, exit the method
}
}
if (node.Tag is string path && node.Checked)
{
await ExecutePlugin(path);
}
// Recursively process all child nodes
foreach (TreeNode child in node.Nodes)
await FixChecked(child);
}
/// <summary>
/// Analyzes individual plugin files.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static async Task AnalyzePlugin(TreeNode node)
{
if (node?.Tag is string path && File.Exists(path))
{
string content = File.ReadAllText(path);
Logger.Log(new string('=', 50), LogLevel.Custom);
Logger.Log($"📄 Script content:{node.Text}\n{content}", LogLevel.Info);
await Task.CompletedTask;
}
else
{
Logger.Log($"❌ Script file not found for plugin: {node?.Text}", LogLevel.Error);
}
}
/// <summary>
/// Executes individual plugin files.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static async Task FixPlugin(TreeNode node)
{
if (node?.Tag is string path && File.Exists(path))
{
Logger.Log($"🔧 Executing Plugin: {node.Text}", LogLevel.Info);
await ExecutePlugin(path);
}
else
{
Logger.Log($"❌ Script file not found for plugin: {node?.Text}", LogLevel.Error);
}
}
public static void RestorePlugin(TreeNode node)
{
Logger.Log($"⚠️ Restore is not available for Plugins: {node?.Text}", LogLevel.Warning);
MessageBox.Show("Restore is not possible for Plugins.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
/// <summary>
/// Checks if the node is a plugin node.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static bool IsPluginNode(TreeNode node)
{
return node?.Tag is string path && path.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Shows a warning message box when the root plugin node is checked.
/// </summary>
/// <returns>True if the user confirmed, otherwise false.</returns>
public static bool ShowPluginWarning(string pluginName)
{
var result = MessageBox.Show(
$"⚠️ WARNING: The plugin '{pluginName}' is an external script. Its execution is outside this apps responsibility and at your own risk.\n" +
"Proceed only if you trust the source of this plugin. Do you want to continue?",
"Plugin Activation Warning",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning
);
return result == DialogResult.Yes; // Return true if "Yes" was clicked
}
}
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.40.124")]
[assembly: AssemblyFileVersion("0.40.124")]
[assembly: AssemblyVersion("0.50.135")]
[assembly: AssemblyFileVersion("0.50.135")]
+7 -11
View File
@@ -107,9 +107,9 @@
this.btnDonate.ForeColor = System.Drawing.Color.White;
this.btnDonate.Location = new System.Drawing.Point(194, 65);
this.btnDonate.Name = "btnDonate";
this.btnDonate.Size = new System.Drawing.Size(179, 31);
this.btnDonate.Size = new System.Drawing.Size(207, 39);
this.btnDonate.TabIndex = 240;
this.btnDonate.Text = "Help me Launch Version 1.0 🚀";
this.btnDonate.Text = "Like Crapfixer? Support future updates on Ko-fi or PayPal";
this.btnDonate.UseVisualStyleBackColor = false;
this.btnDonate.Click += new System.EventHandler(this.btnDonate_Click);
//
@@ -133,31 +133,27 @@
//
this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.button1.Enabled = false;
this.button1.FlatAppearance.BorderColor = System.Drawing.Color.Gainsboro;
this.button1.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(153)))), ((int)(((byte)(180)))), ((int)(((byte)(209)))));
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button1.Font = new System.Drawing.Font("Tahoma", 8F);
this.button1.Location = new System.Drawing.Point(10, 49);
this.button1.Location = new System.Drawing.Point(10, 53);
this.button1.Name = "button1";
this.button1.Padding = new System.Windows.Forms.Padding(20, 0, 0, 0);
this.button1.Size = new System.Drawing.Size(127, 30);
this.button1.Size = new System.Drawing.Size(107, 34);
this.button1.TabIndex = 241;
this.button1.Text = "Settings";
this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.button1.UseVisualStyleBackColor = false;
//
// button2
//
this.button2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.button2.FlatAppearance.BorderColor = System.Drawing.Color.Gainsboro;
this.button2.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(153)))), ((int)(((byte)(180)))), ((int)(((byte)(209)))));
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button2.Font = new System.Drawing.Font("Tahoma", 8F);
this.button2.Location = new System.Drawing.Point(10, 13);
this.button2.Name = "button2";
this.button2.Padding = new System.Windows.Forms.Padding(20, 0, 0, 0);
this.button2.Size = new System.Drawing.Size(127, 30);
this.button2.Size = new System.Drawing.Size(107, 34);
this.button2.TabIndex = 242;
this.button2.Text = "About";
this.button2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.button2.UseVisualStyleBackColor = false;
//
// SettingsView
+22 -4
View File
@@ -38,12 +38,30 @@ namespace Views
if (result == DialogResult.Yes)
{
System.Diagnostics.Process.Start(new ProcessStartInfo
var donationChoice = MessageBox.Show(
"Would you like to donate via PayPal? (Click No for Ko-fi)",
"Choose Your Support Method",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (donationChoice == DialogResult.Yes)
{
FileName = "https://paypal.com/donate?hosted_button_id=MY7HX4QLYR4KG",
UseShellExecute = true
});
System.Diagnostics.Process.Start(new ProcessStartInfo
{
FileName = "https://www.paypal.com/donate/?hosted_button_id=M9DW4VNKH9ECQ",
UseShellExecute = true
});
}
else if (donationChoice == DialogResult.No)
{
System.Diagnostics.Process.Start(new ProcessStartInfo
{
FileName = "https://ko-fi.com/builtbybel",
UseShellExecute = true
});
}
}
}
}
}