diff --git a/CFixer/AppManagerService.cs b/CFixer/AppManagerService.cs
index b3497b3..02ca5a8 100644
--- a/CFixer/AppManagerService.cs
+++ b/CFixer/AppManagerService.cs
@@ -9,7 +9,6 @@ using Windows.Management.Deployment;
namespace CrapFixer
{
-
public class AppAnalysisResult
{
public string AppName { get; set; }
@@ -43,13 +42,18 @@ namespace CrapFixer
}
///
- /// Analyzes the apps based on predefined apps (from resources) and logs the results in MainForm.
+ /// Analyzes the installed apps against provided bloatware patterns and whitelist,
+ /// logs the results, and returns the matches.
///
- ///
- ///
- public async Task> AnalyzeAndLogAppsAsync(string[] predefinedApps)
+ /// List of bloatware keywords to check against
+ /// List of app names to ignore
+ /// If true, scans all apps regardless of bloatware patterns
+ public async Task> AnalyzeAndLogAppsAsync(
+ string[] bloatwarePatterns,
+ string[] whitelistPatterns,
+ bool scanAll)
{
- var apps = await AnalyzeAppsAsync(predefinedApps);
+ var apps = await AnalyzeAppsAsync(bloatwarePatterns, whitelistPatterns, scanAll);
if (apps.Count > 0)
{
@@ -64,37 +68,56 @@ namespace CrapFixer
Logger.Log("✅ No Microsoft Store bloatware apps found.", LogLevel.Info);
}
+ Logger.Log(""); // Add a blank line for spacing
+
return apps;
}
-
///
/// Analyzes the apps based on predefined apps (from resources) and returns matching apps.
///
///
///
- public async Task> AnalyzeAppsAsync(string[] predefinedApps)
+ public async Task> AnalyzeAppsAsync(string[] bloatwarePatterns, string[] whitelistPatterns, bool scanAll = false)
{
Logger.Log("\n🧩 APPS ANALYSIS", LogLevel.Info);
Logger.Log(new string('=', 50), LogLevel.Info);
- await LoadAppsAsync(); // Load all apps before analysis
+ await LoadAppsAsync(); // Load all installed apps
var result = new List();
- // Check each app's name against predefined patterns
foreach (var app in _appDirectory)
{
- foreach (string pattern in predefinedApps)
+ string appName = app.Key.ToLower();
+
+ // Always skip whitelisted apps
+ if (whitelistPatterns.Any(w => appName.Contains(w)))
+ continue;
+
+ if (scanAll)
{
- if (app.Key.ToLower().Contains(pattern.ToLower()))
+ // If wildcard is set, include everything not whitelisted
+ result.Add(new AppAnalysisResult
{
- result.Add(new AppAnalysisResult
+ AppName = app.Key,
+ FullName = app.Value
+ });
+ }
+ else
+ {
+ // Only match against provided patterns
+ foreach (var pattern in bloatwarePatterns)
+ {
+ if (appName.Contains(pattern))
{
- AppName = app.Key,
- FullName = app.Value // Store the full name
- });
- break;
+ result.Add(new AppAnalysisResult
+ {
+ AppName = app.Key,
+ FullName = app.Value
+ });
+ break;
+ }
}
}
}
@@ -171,39 +194,71 @@ namespace CrapFixer
return removedApps; // Return removed apps to update the UI
}
+
///
- /// 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.
+ /// Loads external bloatware and whitelist patterns from a text file (e.g., CFEnhancer.txt).
+ /// Also checks if wildcard (*) is set to scan all apps.
///
- public string[] LoadExternalBloatwareList(string fileName = "CFEnhancer.txt")
+ /// Name of the file to load from (must be in Plugins folder)
+ ///
+ /// A tuple containing:
+ /// - bloatwarePatterns: List of apps to flag as bloatware
+ /// - whitelistPatterns: List of apps to ignore/exclude from detection
+ /// - scanAll: Whether all apps should be shown regardless of matching patterns
+ ///
+ public (string[] bloatwarePatterns, string[] whitelistPatterns, bool scanAll) LoadExternalBloatwarePatterns(string fileName = "CFEnhancer.txt")
{
try
{
string exeDir = AppDomain.CurrentDomain.BaseDirectory;
- string pluginsDir = Path.Combine(exeDir, "plugins");
- string fullPath = Path.Combine(pluginsDir, fileName);
+ string fullPath = Path.Combine(exeDir, "Plugins", fileName);
if (!File.Exists(fullPath))
{
- Logger.Log($"⚠️ The bloatware radar stays basic for now 🧠. Get the CFEnhancer detection list from Options > Plugins ", LogLevel.Warning);
- return Array.Empty();
+ Logger.Log($"⚠️ The bloatware radar stays basic for now 🧠. Get the enhanced detection list from Options > Plugins > CFEnhancer plugin", LogLevel.Warning);
+ return (Array.Empty(), Array.Empty(), false);
}
- var content = File.ReadAllText(fullPath);
- return content.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
- .Select(s => s.Trim())
- .ToArray();
+ var lines = File.ReadAllLines(fullPath);
+ var bloatware = new List(); // Apps to detect as bloatware
+ var whitelist = new List(); // Apps to ignore completely
+ bool scanAll = false; // Set to true if wildcard (*) is present
+
+ foreach (var line in lines)
+ {
+ // Strip comments after "#" and trim whitespace
+ var entry = line.Split('#')[0].Trim();
+
+ // Skip empty lines or lines with only comments
+ if (string.IsNullOrWhiteSpace(entry))
+ continue;
+
+ // Wildcard entry means: show all installed apps
+ if (entry == "*" || entry == "*.*")
+ {
+ scanAll = true;
+ continue;
+ }
+
+ // Entries starting with "!" go to the whitelist (excluded apps)
+ if (entry.StartsWith("!"))
+ whitelist.Add(entry.Substring(1).Trim().ToLower());
+ else
+ bloatware.Add(entry.ToLower()); // All other entries are bloatware patterns
+ }
+
+ return (bloatware.ToArray(), whitelist.ToArray(), scanAll);
}
catch (Exception ex)
{
Logger.Log($"Error reading external bloatware file: {ex.Message}", LogLevel.Warning);
- return Array.Empty();
+ return (Array.Empty(), Array.Empty(), false);
}
}
///
- /// OPTIONALLY!Returns all installed apps in the system.
+ /// OPTIONALLY!Returns all installed apps in the system.
///
///
public async Task> GetAllInstalledAppsAsync()
diff --git a/CFixer/CFixer.csproj b/CFixer/CFixer.csproj
index 1750e2b..4648efc 100644
--- a/CFixer/CFixer.csproj
+++ b/CFixer/CFixer.csproj
@@ -7,7 +7,7 @@
{FA7D5C89-63D3-4AF0-80C2-D650D35E575B}
WinExe
CFixer
- CFixer
+ Crap Fixer
v4.8.1
512
true
@@ -57,7 +57,7 @@
-
+
@@ -78,6 +78,7 @@
+
@@ -128,6 +129,11 @@
+
+ True
+ True
+ Resources.resx
+
UserControl
@@ -152,6 +158,12 @@
OptionsView.cs
+
+ UserControl
+
+
+ ViveView.cs
+
MainForm.cs
@@ -162,6 +174,7 @@
AboutView.cs
+ Designer
PluginsView.cs
@@ -172,17 +185,15 @@
OptionsView.cs
+
+ ViveView.cs
+
SettingsSingleFileGenerator
Settings.Designer.cs
-
- True
- True
- Resources.resx
-
True
Settings.settings
diff --git a/CFixer/Features/AI/ClickToDo.cs b/CFixer/Features/AI/ClickToDo.cs
new file mode 100644
index 0000000..e930188
--- /dev/null
+++ b/CFixer/Features/AI/ClickToDo.cs
@@ -0,0 +1,70 @@
+using Microsoft.Win32;
+using System;
+using System.Threading.Tasks;
+using CrapFixer;
+
+namespace Settings.UI
+{
+ ///
+ /// Disables the Click to Do feature, which also removes its entry from the right-click context menu.
+ /// Only available on Copilot+ PCs running Windows 11 24H2 or newer.
+ /// Requires a PC with an NPU (Neural Processing Unit).
+ ///
+ internal class ClickToDo: FeatureBase
+ {
+ private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\ClickToDo";
+ private const string valueName = "DisableClickToDo";
+ private const int recommendedValue = 1; // 1 = fully disabled, including context menu
+
+ public override string GetFeatureDetails()
+ {
+ return $"{keyName} | Value: {valueName} | Set to: {recommendedValue} (disables Click to Do, removing it from context menus). " +
+ "Note: This setting only applies on Copilot+ PCs with Windows 11 24H2 or newer.";
+ }
+
+
+
+ public override string ID()
+ {
+ return "Disable Click to Do (Only Copilot+ PCs)";
+ }
+
+ public override string Info()
+ {
+ return "Disables Click to Do entirely, including its context menu entry which uses on-device AI to suggest actions based on screen content. Only available on Copilot+ PCs with Windows 11 24H2 or newer.";
+ }
+
+ public override Task CheckFeature()
+ {
+ return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
+ }
+
+ public override Task DoFeature()
+ {
+ try
+ {
+ Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
+ return Task.FromResult(true);
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Error disabling Click to Do: " + ex.Message, LogLevel.Error);
+ return Task.FromResult(false);
+ }
+ }
+
+ public override bool UndoFeature()
+ {
+ try
+ {
+ Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Error re-enabling Click to Do: " + ex.Message, LogLevel.Error);
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CFixer/Features/FeatureLoader.cs b/CFixer/Features/FeatureLoader.cs
index fa6c31f..1719563 100644
--- a/CFixer/Features/FeatureLoader.cs
+++ b/CFixer/Features/FeatureLoader.cs
@@ -1,13 +1,13 @@
-using Settings.Issues;
-using Settings.Ads;
+using Settings.Ads;
using Settings.AI;
using Settings.Edge;
using Settings.Gaming;
+using Settings.Issues;
using Settings.Personalization;
using Settings.Privacy;
using Settings.System;
-using System.Collections.Generic;
using Settings.UI;
+using System.Collections.Generic;
namespace Features
{
@@ -69,6 +69,7 @@ namespace Features
new FeatureNode(new ShowOrHideMostUsedApps()),
new FeatureNode(new ShowTaskViewButton()),
new FeatureNode(new DisableSearchBoxSuggestions()),
+ new FeatureNode(new DisableBingSearch()),
new FeatureNode(new StartLayout()),
new FeatureNode(new TaskbarAlignment()),
new FeatureNode(new Transparency()),
@@ -121,7 +122,7 @@ namespace Features
{
new FeatureNode(new CopilotTaskbar()),
new FeatureNode(new Recall()),
- new FeatureNode(new AskCopilot()),
+ new FeatureNode(new ClickToDo()) { DefaultChecked = false },
}
},
};
diff --git a/CFixer/Features/FeatureManager.cs b/CFixer/Features/FeatureManager.cs
index ca63ef0..2e9ac18 100644
--- a/CFixer/Features/FeatureManager.cs
+++ b/CFixer/Features/FeatureManager.cs
@@ -1,5 +1,6 @@
using Features;
using System;
+using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -16,12 +17,14 @@ namespace CrapFixer
// Public properties to access the analysis results
public static int TotalChecked => totalChecked;
+
public static int IssuesFound => issuesFound;
public static void ResetAnalysis()
{
totalChecked = 0;
issuesFound = 0;
+ Logger.Clear();
}
///
@@ -29,6 +32,9 @@ namespace CrapFixer
///
public static void LoadFeatures(TreeView tree)
{
+ // Hide the TreeView to avoid flickering and visible scroll jump
+ tree.Visible = false;
+
var features = FeatureLoader.Load();
tree.Nodes.Clear();
@@ -43,6 +49,14 @@ namespace CrapFixer
}
tree.ExpandAll(); // expand all nodes
+
+ // Set scroll to top and make TreeView visible
+ tree.BeginInvoke(new Action(() =>
+ {
+ // Ensure the first node is shown at the top (prevents auto-scroll to bottom)
+ if (tree.Nodes.Count > 0) tree.TopNode = tree.Nodes[0];
+ tree.Visible = true;
+ }));
}
///
@@ -166,52 +180,75 @@ namespace CrapFixer
RestoreChecked(child);
}
}
-
-
///
- /// Analyzes a selected feature and logs its status.
+ /// Analyzes a selected feature or, if it's a category, analyzes only checked child features.
///
public static async void AnalyzeFeature(TreeNode node)
{
- // no && node.Checked
+ // Analyze this node if it's a leaf node (not a category)
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)
+ if (isOk)
+ {
+ Logger.Log($"✅ Feature: {fn.Name} is properly configured.", LogLevel.Info);
+ }
+ else
+ {
+ string category = node.Parent?.Text ?? "General";
+ Logger.Log($"❌ Feature: {fn.Name} requires attention.", LogLevel.Warning);
+ Logger.Log($" ➤ {fn.Feature.GetFeatureDetails()}");
Logger.Log(new string('-', 50), LogLevel.Info);
+ }
+ }
+ else
+ {
+ // If it's a category node, analyze only checked child nodes
+ foreach (TreeNode child in node.Nodes)
+ {
+ if (child.Checked)
+ AnalyzeFeature(child);
+ }
}
}
///
- /// Attempts to fix the selected feature and logs the result.
+ /// Attempts to fix the selected feature or, if it is a category, fixes only checked child features.
///
public static async Task FixFeature(TreeNode node)
{
- // no && node.Checked
+ // Try to fix this node if it is NOT a category (i.e., a leaf node)
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
+ // Always fix the selected leaf node, regardless of Checked
bool result = await fn.Feature.DoFeature();
Logger.Log(result
? $"🔧 {fn.Name} - Fixed"
: $"❌ {fn.Name} - ⚠️ Fix failed (This feature may require admin privileges)",
result ? LogLevel.Info : LogLevel.Error);
}
+ else
+ {
+ // If it's a category node, fix only checked child nodes (recursively)
+ foreach (TreeNode child in node.Nodes)
+ {
+ if (child.Checked)
+ await FixFeature(child);
+ }
+ }
}
+
///
- /// Restores the selected feature to its original state and logs the result.
+ /// Restores a selected feature (always) or, if it's a category, only restores checked child features.
+ /// Logs success or failure.
///
public static void RestoreFeature(TreeNode node)
{
- // no && node.Checked
+ // Restore feature node regardless of Checked state
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
bool ok = fn.Feature.UndoFeature();
@@ -220,38 +257,26 @@ namespace CrapFixer
: $"❌ {fn.Name} - Restore failed",
ok ? LogLevel.Info : LogLevel.Error);
}
- }
-
- ///
- /// Recursively previews changes for all checked features.
- ///
- ///
- public static void PreviewChanges(TreeNode node)
- {
- if (node.Tag is FeatureNode fn)
+ else
{
- if (!fn.IsCategory && fn.Feature != null)
- {
- string details = fn.Feature.GetFeatureDetails();
-
- string category = node.Parent?.Text ?? "General";
- Logger.Log($"🛈 [PREVIEW] [{category}] {fn.Name}", LogLevel.Info);
- Logger.Log($" ➤ {details}");
- Logger.Log(new string('-', 50), LogLevel.Info);
- }
-
+ // For category nodes, only restore checked children
foreach (TreeNode child in node.Nodes)
- PreviewChanges(child);
+ {
+ if (child.Checked)
+ RestoreFeature(child);
+ }
}
}
///
- /// Displays help information for the selected feature.
+ /// Displays help information for the selected feature or plugin.
+ /// If a feature is selected, also offers to search online.
///
public static void ShowHelp(TreeNode node)
{
- if (node.Tag is FeatureNode fn && fn.Feature != null)
+ // Show help for features
+ if (node?.Tag is FeatureNode fn && fn.Feature != null)
{
string info = fn.Feature.Info();
MessageBox.Show(
@@ -259,27 +284,36 @@ namespace CrapFixer
$"Help: {fn.Name}",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
+
+ // Optional online help
+ 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)
+ {
+ string searchQuery = Uri.EscapeDataString(fn.Feature.GetFeatureDetails());
+ string webUrl = $"https://www.google.com/search?q={searchQuery}";
+ System.Diagnostics.Process.Start(new ProcessStartInfo
+ {
+ FileName = webUrl,
+ UseShellExecute = true
+ });
+ }
+
+ return;
}
- else
+
+ // Show help for plugins
+ if (!PluginManager.ShowHelp(node))
{
- MessageBox.Show("⚠️ No feature selected or feature is invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show("⚠️ No feature or plugin selected, or help info unavailable.",
+ "Help",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Warning);
}
}
-
- ///
- /// Opens the default web browser to search for help online for the selected feature (Extended ShowHelp).
- ///
- ///
- 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);
- }
- }
-
}
}
\ No newline at end of file
diff --git a/CFixer/Features/Issues/BasicCleanup.cs b/CFixer/Features/Issues/BasicCleanup.cs
index 66a9dbf..d138577 100644
--- a/CFixer/Features/Issues/BasicCleanup.cs
+++ b/CFixer/Features/Issues/BasicCleanup.cs
@@ -23,7 +23,6 @@ namespace Settings.Issues
var totalSize = GetDirectorySize(tempPath);
bool isOk = totalSize <= 50;
-
return Task.FromResult(isOk);
}
@@ -34,13 +33,12 @@ namespace Settings.Issues
}
}
-
public override string GetFeatureDetails()
{
try
{
var totalSize = GetDirectorySize(tempPath);
- return $"Temp folder size: {totalSize} MB (We need also to include cleanmgr in the next run)";
+ return $"Temp folder size: {totalSize} MB (including cleanmgr /sagerun:1 in the next run)";
}
catch (Exception ex)
{
@@ -53,7 +51,7 @@ namespace Settings.Issues
{
try
{
- await CleanTempFolderAsync();
+ await CleanTempFolderAsync();
await RunDiskCleanup();
Logger.Log("Basic Cleanup completed successfully.", LogLevel.Info);
return true;
@@ -65,7 +63,6 @@ namespace Settings.Issues
}
}
-
private async Task CleanTempFolderAsync()
{
var files = await Task.Run(() => Directory.GetFiles(tempPath, "*", SearchOption.AllDirectories));
@@ -75,7 +72,7 @@ namespace Settings.Issues
{
try
{
- await Task.Run(() => File.Delete(file));
+ await Task.Run(() => File.Delete(file));
Logger.Log($"Deleted file: {file}", LogLevel.Info);
}
catch (Exception ex)
@@ -98,7 +95,6 @@ namespace Settings.Issues
}
}
-
// calculate the size of the directory in MB
private long GetDirectorySize(string directory)
{
@@ -110,7 +106,6 @@ namespace Settings.Issues
// Calculate size of all files
size += directoryInfo.GetFiles("*", SearchOption.AllDirectories).Sum(file => file.Length);
-
return size / (1024 * 1024); // return size in MB
}
catch (Exception ex)
@@ -144,13 +139,13 @@ namespace Settings.Issues
using (var process1 = Process.Start(startInfo1))
{
if (process1 != null)
- await Task.Run(() => process1.WaitForExit());
+ await Task.Run(() => process1.WaitForExit());
}
using (var process2 = Process.Start(startInfo2))
{
if (process2 != null)
- await Task.Run(() => process2.WaitForExit());
+ await Task.Run(() => process2.WaitForExit());
}
}
catch (Exception ex)
@@ -159,8 +154,7 @@ namespace Settings.Issues
}
}
-
// Undo method: Cleanup cannot be undone, so return false
public override bool UndoFeature() => false;
}
-}
+}
\ No newline at end of file
diff --git a/CFixer/Features/Issues/WingetUpgrade.cs b/CFixer/Features/Issues/WingetUpgrade.cs
index 3ca547d..578f6ac 100644
--- a/CFixer/Features/Issues/WingetUpgrade.cs
+++ b/CFixer/Features/Issues/WingetUpgrade.cs
@@ -1,7 +1,8 @@
-using System;
+using CrapFixer;
+using System;
using System.Diagnostics;
+using System.Drawing;
using System.Threading.Tasks;
-using CrapFixer;
namespace Settings.System
{
@@ -29,9 +30,9 @@ namespace Settings.System
try
{
- string output = await ExecuteCommand("winget upgrade --include-unknown");
+ string output = await ExecuteCommand("winget upgrade --include-unknown" );
- Logger.Log("Winget upgrade check:\n" + output, LogLevel.Info);
+ Logger.Log("Winget upgrade check:\n" + output, LogLevel.Info, new Font("Cascadia Mono", 8.25f));
return output.ToLower().Contains("available");
}
@@ -122,4 +123,4 @@ namespace Settings.System
return tcs.Task;
}
}
-}
+}
\ No newline at end of file
diff --git a/CFixer/Features/UI/BingSearch.cs b/CFixer/Features/UI/BingSearch.cs
new file mode 100644
index 0000000..568a251
--- /dev/null
+++ b/CFixer/Features/UI/BingSearch.cs
@@ -0,0 +1,62 @@
+using Microsoft.Win32;
+using System;
+using System.Threading.Tasks;
+using CrapFixer;
+
+namespace Settings.UI
+{
+ internal class DisableBingSearch : FeatureBase
+ {
+ private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search";
+ private const string valueName = "BingSearchEnabled";
+ private const int recommendedValue = 0;
+
+ public override string GetFeatureDetails()
+ {
+ return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
+ }
+
+ public override string ID()
+ {
+ return "Disable Bing Search";
+ }
+
+ public override string Info()
+ {
+ return "This feature disables Bing integration in Windows Search.";
+ }
+
+ public override Task CheckFeature()
+ {
+ return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
+ }
+
+ public override Task DoFeature()
+ {
+ try
+ {
+ Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
+ return Task.FromResult(true);
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Error in DisableBingSearch: " + ex.Message, LogLevel.Error);
+ return Task.FromResult(false);
+ }
+ }
+
+ public override bool UndoFeature()
+ {
+ try
+ {
+ Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Error undoing DisableBingSearch: " + ex.Message, LogLevel.Error);
+ return false;
+ }
+ }
+ }
+}
diff --git a/CFixer/Helpers/Logger.cs b/CFixer/Helpers/Logger.cs
index 7c983fc..4ce2dc2 100644
--- a/CFixer/Helpers/Logger.cs
+++ b/CFixer/Helpers/Logger.cs
@@ -7,25 +7,37 @@ using System.Windows.Forms;
///
public static class Logger
{
+ ///
+ /// The RichTextBox control to which log messages are written.
+ ///
public static RichTextBox OutputBox;
- private static readonly Font DefaultFont = new Font("Consolas", 8.25f, FontStyle.Regular);
+ private static readonly Font DefaultFont = new Font("Tahoma", 8.25f, FontStyle.Regular);
- public static void Log(string message, LogLevel level = LogLevel.Info)
+ ///
+ /// Writes a message with an optional log level and custom font.
+ ///
+ /// The message to display.
+ /// The log level (e.g., Info, Warning, Error).
+ /// An optional font for the message.
+ public static void Log(string message, LogLevel level = LogLevel.Info, Font customFont = null)
{
if (OutputBox == null) return;
if (OutputBox.InvokeRequired)
{
- OutputBox.Invoke(new Action(() => LogInternal(message, level)));
+ OutputBox.Invoke(new Action(() => LogInternal(message, level, customFont)));
}
else
{
- LogInternal(message, level);
+ LogInternal(message, level, customFont);
}
}
- private static void LogInternal(string message, LogLevel level)
+ ///
+ /// Internal method to append text to the RichTextBox with formatting.
+ ///
+ private static void LogInternal(string message, LogLevel level, Font customFont = null)
{
// string prefix = $"[{DateTime.Now:HH:mm:ss}] [{level}] ";
string fullMessage = message + Environment.NewLine;
@@ -51,10 +63,11 @@ public static class Logger
break;
}
- // Append text with color
+ // Append formatted message
OutputBox.SelectionStart = OutputBox.TextLength;
OutputBox.SelectionLength = 0;
OutputBox.SelectionColor = color;
+ OutputBox.SelectionFont = customFont ?? DefaultFont; // use custom font if provided, otherwise use default
OutputBox.AppendText(fullMessage);
// Reset selection to default
@@ -62,8 +75,29 @@ public static class Logger
OutputBox.SelectionFont = DefaultFont; // reset font
OutputBox.ScrollToCaret(); // scroll to the end
}
+
+ ///
+ /// Clears the log output.
+ ///
+ public static void Clear()
+ {
+ if (OutputBox == null || OutputBox.IsDisposed)
+ return;
+
+ if (OutputBox.InvokeRequired)
+ {
+ OutputBox.Invoke(new Action(Clear));
+ return;
+ }
+
+ OutputBox.Clear();
+ OutputBox.SelectionColor = Color.Black;
+ }
}
+///
+/// Log level types used to define message severity.
+///
public enum LogLevel
{
Info,
diff --git a/CFixer/Helpers/OSHelper.cs b/CFixer/Helpers/OSHelper.cs
index 83d705c..0453df6 100644
--- a/CFixer/Helpers/OSHelper.cs
+++ b/CFixer/Helpers/OSHelper.cs
@@ -1,9 +1,9 @@
-using System.Collections.ObjectModel;
+using System;
+using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Threading.Tasks;
using Microsoft.Win32;
-// This file is part of CFixer.
namespace OSHelper
{
internal class OSHelper
@@ -14,37 +14,63 @@ namespace OSHelper
{
try
{
- using (PowerShell powerShellInstance = PowerShell.Create())
+ using (PowerShell ps = PowerShell.Create())
{
- powerShellInstance.AddScript("Get-CimInstance -ClassName Win32_OperatingSystem");
- Collection psOutput = powerShellInstance.Invoke();
+ ps.AddScript("Get-CimInstance -ClassName Win32_OperatingSystem");
+ var results = ps.Invoke();
- foreach (PSObject outputItem in psOutput)
+ foreach (var result in results)
{
- if (outputItem != null)
- {
- string productName = outputItem.Properties["Caption"]?.Value?.ToString();
- if (!string.IsNullOrEmpty(productName))
- {
- string osVersion = productName.Contains("Windows 10") ? "Windows 10" : "Windows 11";
+ if (result == null) continue;
- using (RegistryKey displayVersionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"))
+ string caption = result.Properties["Caption"]?.Value?.ToString();
+ string version = result.Properties["Version"]?.Value?.ToString();
+ string build = result.Properties["BuildNumber"]?.Value?.ToString();
+
+ string displayVersion = Registry.GetValue(
+ @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion",
+ "DisplayVersion", "")?.ToString();
+
+ // UBR = Update Build Revision
+ string ubr = Registry.GetValue(
+ @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion",
+ "UBR", 0)?.ToString();
+
+ bool isInsider = false;
+ string ring = null;
+
+ using (var insiderKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\UpdateOrchestrator"))
+ {
+ if (insiderKey != null)
+ {
+ object enabled = insiderKey.GetValue("EnableInsiderBuilds");
+ if (enabled != null && Convert.ToInt32(enabled) == 1)
{
- if (displayVersionKey != null)
- {
- string displayVersion = displayVersionKey.GetValue("DisplayVersion")?.ToString();
- return $"{osVersion} ({displayVersion})";
- }
+ isInsider = true;
+ ring = insiderKey.GetValue("Ring")?.ToString();
}
- return osVersion;
}
}
+
+ string osName = caption?.Contains("Windows 11") == true ? "Windows 11" :
+ caption?.Contains("Windows 10") == true ? "Windows 10" :
+ caption ?? "Unknown OS";
+
+ string fullBuild = !string.IsNullOrEmpty(build) && !string.IsNullOrEmpty(ubr)
+ ? $"{build}.{ubr}"
+ : build ?? "unknown";
+
+ string insiderInfo = isInsider ? $" (Insider: {ring})" : "";
+
+ return $"{osName} {displayVersion}{insiderInfo} (Build {fullBuild})";
}
}
}
- catch
+ catch (Exception ex)
{
+ return $"OS info unavailable: {ex.Message}";
}
+
return "OS not supported";
});
}
diff --git a/CFixer/Helpers/Utils.cs b/CFixer/Helpers/Utils.cs
index ea4b320..05510a2 100644
--- a/CFixer/Helpers/Utils.cs
+++ b/CFixer/Helpers/Utils.cs
@@ -3,55 +3,65 @@ using System;
using System.Diagnostics;
using System.Windows.Forms;
-// This file is part of CFixer.
namespace CrapFixer
{
- internal class Utils
+ internal static class Utils
{
+ private const string GitHubUrl = "https://github.com/builtbybel/CrapFixer";
+
///
- /// Checks if a registry value is equal to a specified integer.
+ /// Checks if a registry value equals a specified integer.
///
- ///
- ///
- ///
- ///
public static bool IntEquals(string keyName, string valueName, int expectedValue)
{
try
{
- var value = Registry.GetValue(keyName, valueName, null);
- return (value != null && (int)value == expectedValue);
+ object value = Registry.GetValue(keyName, valueName, null);
+ return value is int intValue && intValue == expectedValue;
}
catch (Exception ex)
-
{
- MessageBox.Show(keyName, ex.Message, MessageBoxButtons.OK);
+ Logger.Log($"Registry check failed for {keyName}\\{valueName}: {ex.Message}", LogLevel.Error);
return false;
}
}
///
- /// Checks if a registry value is equal to a specified string.
+ /// Checks if a registry value equals a specified string.
///
- ///
- ///
- ///
- ///
public static bool StringEquals(string keyName, string valueName, string expectedValue)
{
try
{
- var value = Registry.GetValue(keyName, valueName, null);
-
- return (value != null && (string)value == expectedValue);
+ object value = Registry.GetValue(keyName, valueName, null);
+ return value is string strValue && strValue == expectedValue;
}
catch (Exception ex)
{
- MessageBox.Show(keyName, ex.Message, MessageBoxButtons.OK);
+ Logger.Log($"Registry check failed for {keyName}\\{valueName}: {ex.Message}", LogLevel.Error);
return false;
}
}
+ ///
+ /// Opens the GitHub project page in the default browser.
+ ///
+ public static void OpenGitHubPage(object sender, EventArgs e)
+ {
+ try
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = GitHubUrl,
+ UseShellExecute = true
+ });
+ }
+ catch (Exception ex)
+ {
+ Logger.Log($"Failed to open GitHub page: {ex.Message}", LogLevel.Error);
+ }
+ }
+
///
/// Restarts Windows Explorer to apply UI changes.
///
@@ -61,22 +71,19 @@ namespace CrapFixer
{
Logger.Log("Restarting Windows Explorer to apply UI changes...", LogLevel.Info);
- // Kill all explorer instances
foreach (var process in Process.GetProcessesByName("explorer"))
{
process.Kill();
process.WaitForExit();
}
- // Restart explorer
Process.Start("explorer.exe");
-
- Logger.Log("Explorer restarted successfully. Changes should now be visible.", LogLevel.Info);
+ Logger.Log("Explorer restarted successfully.", LogLevel.Info);
}
catch (Exception ex)
{
- Logger.Log("Failed to restart Explorer: " + ex.Message, LogLevel.Error);
+ Logger.Log($"Failed to restart Explorer: {ex.Message}", LogLevel.Error);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/CFixer/IniStateManager.cs b/CFixer/IniStateManager.cs
index 7daf5e8..a53f864 100644
--- a/CFixer/IniStateManager.cs
+++ b/CFixer/IniStateManager.cs
@@ -27,7 +27,9 @@ public static class IniStateManager
lines.Add("[APP]");
lines.Add($"Width={form.Width}");
lines.Add($"Height={form.Height}");
- lines.Add(""); // empty line for spacing
+ lines.Add($"Top={form.Top}");
+ lines.Add($"Left={form.Left}");
+ // lines.Add(""); // empty line for spacing
// Append new FEATURES section (TreeView nodes states)
lines.Add("[FEATURES]");
@@ -62,8 +64,75 @@ public static class IniStateManager
}
}
- // Loads global states (App size, TreeView nodes states) from the INI file
- public static void Load(TreeView tree, Form form)
+ // Loads the global states (App size, TreeView nodes states) if enabled
+ public static void LoadFeaturesIfEnabled(TreeView tree)
+ {
+ if (IsViewSettingEnabled("SETTINGS", "checkSaveToINI"))
+ LoadFeatureStates(tree);
+ }
+
+ public static void ApplyWindowState(Form form)
+ {
+ if (File.Exists(IniPath))
+ {
+ // Load window size and position from INI file
+ LoadWindowState(form);
+ form.StartPosition = FormStartPosition.Manual;
+ }
+ else
+ {
+ // If INI file doesn't exist, set default position
+ form.StartPosition = FormStartPosition.CenterScreen;
+ }
+ }
+
+ // Loads only the window size and position from the INI file
+ public static void LoadWindowState(Form form)
+ {
+ if (!File.Exists(IniPath)) return;
+
+ var lines = File.ReadAllLines(IniPath);
+ var section = "";
+
+ foreach (var line in lines)
+ {
+ var trimmed = line.Trim();
+ if (string.IsNullOrWhiteSpace(trimmed)) continue;
+
+ // Check if line is a section header
+ if (trimmed.StartsWith("[") && trimmed.EndsWith("]"))
+ {
+ section = trimmed;
+ continue;
+ }
+
+ if (section == "[APP]")
+ {
+ // Split line into key and value
+ var parts = trimmed.Split(new[] { '=' }, 2);
+ if (parts.Length != 2) continue;
+
+ var key = parts[0].Trim();
+ var value = parts[1].Trim();
+
+ // Parse and apply window size and position
+ if (int.TryParse(value, out int size))
+ {
+ if (key.Equals("Width", StringComparison.OrdinalIgnoreCase))
+ form.Width = size;
+ else if (key.Equals("Height", StringComparison.OrdinalIgnoreCase))
+ form.Height = size;
+ else if (key.Equals("Top", StringComparison.OrdinalIgnoreCase))
+ form.Top = size;
+ else if (key.Equals("Left", StringComparison.OrdinalIgnoreCase))
+ form.Left = size;
+ }
+ }
+ }
+ }
+
+ // Loads only the feature states (TreeView node checked states) from the INI file
+ public static void LoadFeatureStates(TreeView tree)
{
if (!File.Exists(IniPath)) return;
@@ -76,37 +145,28 @@ public static class IniStateManager
var trimmed = line.Trim();
if (string.IsNullOrWhiteSpace(trimmed)) continue;
- // Check if line is a section
+ // Check if line is a section header
if (trimmed.StartsWith("[") && trimmed.EndsWith("]"))
{
section = trimmed;
continue;
}
- // Split line into key and value
- var parts = trimmed.Split(new[] { '=' }, 2);
- if (parts.Length != 2) continue;
-
- var key = parts[0].Trim();
- var value = parts[1].Trim();
-
if (section == "[FEATURES]")
{
+ // Split line into key and value
+ var parts = trimmed.Split(new[] { '=' }, 2);
+ if (parts.Length != 2) continue;
+
+ var key = parts[0].Trim();
+ var value = parts[1].Trim();
+
+ // Save checked state for each feature node
states[key] = value.ToLower() == "true";
}
- else if (section == "[APP]")
- {
- if (int.TryParse(value, out int size))
- {
- if (key.Equals("Width", StringComparison.OrdinalIgnoreCase))
- form.Width = size;
- else if (key.Equals("Height", StringComparison.OrdinalIgnoreCase))
- form.Height = size;
- }
- }
}
- // Apply saved feature states to tree nodes
+ // Apply saved feature states to the TreeView nodes recursively
ApplyStates(tree.Nodes, states);
}
diff --git a/CFixer/MainForm.Designer.cs b/CFixer/MainForm.Designer.cs
index 31702f1..b228ef0 100644
--- a/CFixer/MainForm.Designer.cs
+++ b/CFixer/MainForm.Designer.cs
@@ -29,7 +29,6 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.panelContainer = new System.Windows.Forms.Panel();
this.panelContent = new System.Windows.Forms.Panel();
this.btnAnalyze = new System.Windows.Forms.Button();
@@ -38,10 +37,9 @@
this.treeFeatures = new System.Windows.Forms.TreeView();
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.analyzeMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.previewMarkedFeatureToolStripMenuItem = 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.seperatorToolStripMenuItem = new System.Windows.Forms.ToolStripSeparator();
this.helpMarkedFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.Apps = new System.Windows.Forms.TabPage();
this.checkedListBoxApps = new System.Windows.Forms.CheckedListBox();
@@ -50,15 +48,17 @@
this.rtbLogger = new System.Windows.Forms.RichTextBox();
this.btnFix = new System.Windows.Forms.Button();
this.panelHeader = new System.Windows.Forms.Panel();
+ this.btnGitHub = new System.Windows.Forms.Button();
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.linkUpdateCheck = new System.Windows.Forms.LinkLabel();
- this.btnSettings = new System.Windows.Forms.Button();
- this.btnHome = new System.Windows.Forms.Button();
+ this.btnTools = new System.Windows.Forms.Button();
+ this.btnFixer = new System.Windows.Forms.Button();
this.linkSelection = new System.Windows.Forms.LinkLabel();
+ this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.panelContainer.SuspendLayout();
this.panelContent.SuspendLayout();
this.tabControl.SuspendLayout();
@@ -77,15 +77,15 @@
| 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.Location = new System.Drawing.Point(90, 69);
this.panelContainer.Name = "panelContainer";
- this.panelContainer.Size = new System.Drawing.Size(611, 382);
+ this.panelContainer.Size = new System.Drawing.Size(613, 375);
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.BackColor = System.Drawing.Color.White;
this.panelContent.Controls.Add(this.btnAnalyze);
this.panelContent.Controls.Add(this.tabControl);
this.panelContent.Controls.Add(this.groupBox);
@@ -93,7 +93,7 @@
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.Size = new System.Drawing.Size(613, 375);
this.panelContent.TabIndex = 205;
//
// btnAnalyze
@@ -102,7 +102,7 @@
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.Location = new System.Drawing.Point(268, 339);
this.btnAnalyze.Name = "btnAnalyze";
this.btnAnalyze.Size = new System.Drawing.Size(121, 29);
this.btnAnalyze.TabIndex = 1;
@@ -116,45 +116,42 @@
| 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.ItemSize = new System.Drawing.Size(68, 21);
+ this.tabControl.Location = new System.Drawing.Point(7, 5);
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.Size = new System.Drawing.Size(255, 363);
+ this.tabControl.SizeMode = System.Windows.Forms.TabSizeMode.FillToRight;
this.tabControl.TabIndex = 199;
//
// Windows
//
+ this.Windows.AutoScroll = true;
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.Location = new System.Drawing.Point(4, 25);
this.Windows.Name = "Windows";
- this.Windows.Padding = new System.Windows.Forms.Padding(3);
- this.Windows.Size = new System.Drawing.Size(262, 340);
+ this.Windows.Size = new System.Drawing.Size(247, 334);
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.BackColor = System.Drawing.Color.White;
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.Location = new System.Drawing.Point(0, 0);
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.Size = new System.Drawing.Size(247, 334);
+ this.treeFeatures.TabIndex = 0;
this.treeFeatures.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeFeatures_AfterCheck);
this.treeFeatures.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeFeatures_MouseDown);
//
@@ -162,14 +159,13 @@
//
this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.analyzeMarkedFeatureToolStripMenuItem,
- this.previewMarkedFeatureToolStripMenuItem,
this.fixMarkedFeatureToolStripMenuItem,
- this.seperatorToolStripMenuItem,
this.restoreMarkedFeatureToolStripMenuItem,
+ this.seperatorToolStripMenuItem,
this.helpMarkedFeatureToolStripMenuItem});
this.contextMenuStrip.Name = "contextManualMenu";
this.contextMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
- this.contextMenuStrip.Size = new System.Drawing.Size(119, 120);
+ this.contextMenuStrip.Size = new System.Drawing.Size(119, 98);
//
// analyzeMarkedFeatureToolStripMenuItem
//
@@ -178,13 +174,6 @@
this.analyzeMarkedFeatureToolStripMenuItem.Text = "Analyze";
this.analyzeMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.analyzeMarkedFeatureToolStripMenuItem_Click);
//
- // previewMarkedFeatureToolStripMenuItem
- //
- this.previewMarkedFeatureToolStripMenuItem.Name = "previewMarkedFeatureToolStripMenuItem";
- this.previewMarkedFeatureToolStripMenuItem.Size = new System.Drawing.Size(118, 22);
- this.previewMarkedFeatureToolStripMenuItem.Text = "Preview";
- this.previewMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.previewMarkedFeatureToolStripMenuItem_Click);
- //
// fixMarkedFeatureToolStripMenuItem
//
this.fixMarkedFeatureToolStripMenuItem.Name = "fixMarkedFeatureToolStripMenuItem";
@@ -192,11 +181,6 @@
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";
@@ -204,6 +188,11 @@
this.restoreMarkedFeatureToolStripMenuItem.Text = "Restore";
this.restoreMarkedFeatureToolStripMenuItem.Click += new System.EventHandler(this.restoreMarkedFeatureToolStripMenuItem_Click);
//
+ // seperatorToolStripMenuItem
+ //
+ this.seperatorToolStripMenuItem.Name = "seperatorToolStripMenuItem";
+ this.seperatorToolStripMenuItem.Size = new System.Drawing.Size(115, 6);
+ //
// helpMarkedFeatureToolStripMenuItem
//
this.helpMarkedFeatureToolStripMenuItem.Name = "helpMarkedFeatureToolStripMenuItem";
@@ -214,30 +203,28 @@
//
// Apps
//
- this.Apps.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
+ this.Apps.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240)))));
this.Apps.Controls.Add(this.checkedListBoxApps);
- this.Apps.Location = new System.Drawing.Point(4, 32);
+ this.Apps.Location = new System.Drawing.Point(4, 25);
this.Apps.Name = "Apps";
- this.Apps.Padding = new System.Windows.Forms.Padding(3);
- this.Apps.Size = new System.Drawing.Size(262, 340);
+ this.Apps.Size = new System.Drawing.Size(247, 334);
this.Apps.TabIndex = 1;
- this.Apps.Text = "Apps";
+ this.Apps.Text = "Applications";
//
// checkedListBoxApps
//
- this.checkedListBoxApps.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
+ this.checkedListBoxApps.BackColor = System.Drawing.Color.White;
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.Location = new System.Drawing.Point(0, 0);
this.checkedListBoxApps.Name = "checkedListBoxApps";
- this.checkedListBoxApps.Size = new System.Drawing.Size(256, 334);
+ this.checkedListBoxApps.Size = new System.Drawing.Size(247, 334);
this.checkedListBoxApps.Sorted = true;
this.checkedListBoxApps.TabIndex = 336;
- this.checkedListBoxApps.ThreeDCheckBoxes = true;
//
// groupBox
//
@@ -247,9 +234,10 @@
this.groupBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(252)))), ((int)(((byte)(252)))));
this.groupBox.Controls.Add(this.comboLogActions);
this.groupBox.Controls.Add(this.rtbLogger);
- this.groupBox.Location = new System.Drawing.Point(280, 21);
+ this.groupBox.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
+ this.groupBox.Location = new System.Drawing.Point(268, 21);
this.groupBox.Name = "groupBox";
- this.groupBox.Size = new System.Drawing.Size(320, 317);
+ this.groupBox.Size = new System.Drawing.Size(334, 310);
this.groupBox.TabIndex = 200;
this.groupBox.TabStop = false;
//
@@ -257,13 +245,14 @@
//
this.comboLogActions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
+ this.comboLogActions.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240)))));
this.comboLogActions.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboLogActions.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.comboLogActions.Font = new System.Drawing.Font("Tahoma", 8.25F);
this.comboLogActions.FormattingEnabled = true;
- this.comboLogActions.Location = new System.Drawing.Point(7, 292);
+ this.comboLogActions.Location = new System.Drawing.Point(7, 285);
this.comboLogActions.Name = "comboLogActions";
- this.comboLogActions.Size = new System.Drawing.Size(305, 21);
+ this.comboLogActions.Size = new System.Drawing.Size(319, 21);
this.comboLogActions.TabIndex = 210;
this.comboLogActions.Visible = false;
//
@@ -274,13 +263,13 @@
| 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.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.rtbLogger.Location = new System.Drawing.Point(7, 19);
this.rtbLogger.Name = "rtbLogger";
- this.rtbLogger.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
- this.rtbLogger.Size = new System.Drawing.Size(305, 273);
+ this.rtbLogger.Size = new System.Drawing.Size(319, 263);
this.rtbLogger.TabIndex = 195;
this.rtbLogger.Text = "";
+ this.rtbLogger.WordWrap = false;
//
// btnFix
//
@@ -288,7 +277,7 @@
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.Location = new System.Drawing.Point(482, 339);
this.btnFix.Name = "btnFix";
this.btnFix.Size = new System.Drawing.Size(121, 29);
this.btnFix.TabIndex = 2;
@@ -299,6 +288,7 @@
// panelHeader
//
this.panelHeader.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(77)))), ((int)(((byte)(77)))));
+ this.panelHeader.Controls.Add(this.btnGitHub);
this.panelHeader.Controls.Add(this.lblOSInfo);
this.panelHeader.Controls.Add(this.lblVersionInfo);
this.panelHeader.Controls.Add(this.lblHeader);
@@ -310,21 +300,42 @@
this.panelHeader.TabIndex = 204;
this.panelHeader.Paint += new System.Windows.Forms.PaintEventHandler(this.panelHeader_Paint);
//
+ // btnGitHub
+ //
+ this.btnGitHub.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnGitHub.AutoSize = true;
+ this.btnGitHub.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.btnGitHub.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(170)))), ((int)(((byte)(210)))));
+ this.btnGitHub.FlatAppearance.BorderSize = 0;
+ this.btnGitHub.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnGitHub.Font = new System.Drawing.Font("Tahoma", 8F);
+ this.btnGitHub.ForeColor = System.Drawing.Color.Gainsboro;
+ this.btnGitHub.Location = new System.Drawing.Point(657, 7);
+ this.btnGitHub.Name = "btnGitHub";
+ this.btnGitHub.Size = new System.Drawing.Size(40, 40);
+ this.btnGitHub.TabIndex = 201;
+ this.btnGitHub.TabStop = false;
+ this.toolTip.SetToolTip(this.btnGitHub, "Love CrapFixer? It’s open source — but your support keeps it alive! 💖");
+ this.btnGitHub.UseVisualStyleBackColor = true;
+ this.btnGitHub.Click += new System.EventHandler(this.btnGitHub_Click);
+ //
// lblOSInfo
//
this.lblOSInfo.AutoSize = true;
- this.lblOSInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
+ this.lblOSInfo.BackColor = System.Drawing.Color.Transparent;
+ this.lblOSInfo.Font = new System.Drawing.Font("Tahoma", 7.6F);
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.Size = new System.Drawing.Size(120, 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.BackColor = System.Drawing.Color.Transparent;
+ this.lblVersionInfo.Font = new System.Drawing.Font("Tahoma", 7.6F);
this.lblVersionInfo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.lblVersionInfo.Location = new System.Drawing.Point(198, 15);
this.lblVersionInfo.Name = "lblVersionInfo";
@@ -335,6 +346,8 @@
// lblHeader
//
this.lblHeader.AutoEllipsis = true;
+ this.lblHeader.BackColor = System.Drawing.Color.Transparent;
+ this.lblHeader.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblHeader.Font = new System.Drawing.Font("Tahoma", 14F, System.Drawing.FontStyle.Bold);
this.lblHeader.ForeColor = System.Drawing.Color.White;
this.lblHeader.Location = new System.Drawing.Point(89, 9);
@@ -342,29 +355,35 @@
this.lblHeader.Size = new System.Drawing.Size(117, 25);
this.lblHeader.TabIndex = 1;
this.lblHeader.Text = "CrapFixer";
+ this.toolTip.SetToolTip(this.lblHeader, "Click here to visit the CrapFixer website at github.com/builtbybel/crapfixer");
this.lblHeader.UseCompatibleTextRendering = true;
//
// pictureHeader
//
- this.pictureHeader.Image = ((System.Drawing.Image)(resources.GetObject("pictureHeader.Image")));
+ this.pictureHeader.BackColor = System.Drawing.Color.Transparent;
+ this.pictureHeader.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.pictureHeader.Image = global::CFixer.Properties.Resources.AppIcon;
+ this.pictureHeader.InitialImage = null;
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;
+ this.toolTip.SetToolTip(this.pictureHeader, "Click here to visit the CrapFixer website at github.com/builtbybel/crapfixer");
//
// 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.Cursor = System.Windows.Forms.Cursors.Default;
+ this.btnRestore.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(170)))), ((int)(((byte)(210)))));
+ this.btnRestore.FlatAppearance.BorderSize = 0;
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.Font = new System.Drawing.Font("Tahoma", 8F);
+ this.btnRestore.ForeColor = System.Drawing.Color.Gainsboro;
+ this.btnRestore.Location = new System.Drawing.Point(10, 142);
this.btnRestore.Name = "btnRestore";
- this.btnRestore.Size = new System.Drawing.Size(99, 69);
+ this.btnRestore.Size = new System.Drawing.Size(80, 60);
this.btnRestore.TabIndex = 198;
this.btnRestore.TabStop = false;
this.btnRestore.Text = "&Restore";
@@ -379,46 +398,48 @@
this.linkUpdateCheck.AutoSize = true;
this.linkUpdateCheck.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.linkUpdateCheck.LinkColor = System.Drawing.Color.White;
- this.linkUpdateCheck.Location = new System.Drawing.Point(595, 447);
+ this.linkUpdateCheck.Location = new System.Drawing.Point(590, 447);
this.linkUpdateCheck.Name = "linkUpdateCheck";
- this.linkUpdateCheck.Size = new System.Drawing.Size(95, 13);
+ this.linkUpdateCheck.Size = new System.Drawing.Size(107, 13);
this.linkUpdateCheck.TabIndex = 203;
this.linkUpdateCheck.TabStop = true;
- this.linkUpdateCheck.Text = "Check for updates";
- this.linkUpdateCheck.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ this.linkUpdateCheck.Text = "Check for updates...";
+ this.linkUpdateCheck.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ this.linkUpdateCheck.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkUpdateCheck_LinkClicked);
//
- // btnSettings
+ // btnTools
//
- 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;
+ this.btnTools.AutoEllipsis = true;
+ this.btnTools.Cursor = System.Windows.Forms.Cursors.Default;
+ this.btnTools.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(170)))), ((int)(((byte)(210)))));
+ this.btnTools.FlatAppearance.BorderSize = 0;
+ this.btnTools.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnTools.Font = new System.Drawing.Font("Tahoma", 8F);
+ this.btnTools.ForeColor = System.Drawing.Color.Gainsboro;
+ this.btnTools.Location = new System.Drawing.Point(10, 210);
+ this.btnTools.Name = "btnTools";
+ this.btnTools.Size = new System.Drawing.Size(80, 60);
+ this.btnTools.TabIndex = 205;
+ this.btnTools.TabStop = false;
+ this.btnTools.Text = "&Tools";
+ this.btnTools.UseVisualStyleBackColor = true;
//
- // btnHome
+ // btnFixer
//
- 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 = "&Fixer";
- this.btnHome.UseVisualStyleBackColor = false;
+ this.btnFixer.AutoEllipsis = true;
+ this.btnFixer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(150)))), ((int)(((byte)(200)))), ((int)(((byte)(240)))));
+ this.btnFixer.Cursor = System.Windows.Forms.Cursors.Default;
+ this.btnFixer.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(170)))), ((int)(((byte)(210)))));
+ this.btnFixer.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnFixer.Font = new System.Drawing.Font("Tahoma", 8F);
+ this.btnFixer.ForeColor = System.Drawing.Color.Gainsboro;
+ this.btnFixer.Location = new System.Drawing.Point(10, 74);
+ this.btnFixer.Name = "btnFixer";
+ this.btnFixer.Size = new System.Drawing.Size(80, 60);
+ this.btnFixer.TabIndex = 206;
+ this.btnFixer.TabStop = false;
+ this.btnFixer.Text = "&Fixer";
+ this.btnFixer.UseVisualStyleBackColor = false;
//
// linkSelection
//
@@ -441,15 +462,17 @@
//
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.AutoScroll = true;
+ this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(103)))), ((int)(((byte)(103)))), ((int)(((byte)(103)))));
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.btnFixer);
+ this.Controls.Add(this.btnTools);
this.Controls.Add(this.panelHeader);
this.Controls.Add(this.btnRestore);
this.Controls.Add(this.linkUpdateCheck);
this.Controls.Add(this.panelContainer);
+ this.MinimumSize = new System.Drawing.Size(642, 337);
this.Name = "MainForm";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
@@ -495,13 +518,14 @@
private System.Windows.Forms.Panel panelContent;
private System.Windows.Forms.LinkLabel linkUpdateCheck;
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.Button btnTools;
+ private System.Windows.Forms.Button btnFixer;
private System.Windows.Forms.LinkLabel linkSelection;
- private System.Windows.Forms.ToolStripMenuItem previewMarkedFeatureToolStripMenuItem;
private System.Windows.Forms.ComboBox comboLogActions;
+ private System.Windows.Forms.TreeView treeFeatures;
+ private System.Windows.Forms.Button btnGitHub;
+ private System.Windows.Forms.ToolTip toolTip;
}
}
diff --git a/CFixer/MainForm.cs b/CFixer/MainForm.cs
index c1aa126..954c3f1 100644
--- a/CFixer/MainForm.cs
+++ b/CFixer/MainForm.cs
@@ -4,6 +4,7 @@ using CFixer.Views;
using System;
using System.Diagnostics;
using System.Drawing;
+using System.Drawing.Drawing2D;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -21,6 +22,7 @@ namespace CrapFixer
public MainForm()
{
InitializeComponent();
+ IniStateManager.ApplyWindowState(this);
// Set up the main navigation manager and logger
_navigationManager = new NavigationManager(panelContainer);
@@ -28,66 +30,67 @@ namespace CrapFixer
// Set up log actions controller
_logActions = new LogActions(rtbLogger);
- _logActionsController = new LogActionsController(comboLogActions, _logActions);
+ }
- // Load features and plugins, and restore INI state if enabled
+ private async void MainForm_Shown(object sender, EventArgs e)
+ {
+ await InitializeUI(); // _ = InitializeUI();
+ InitializeAppState();
+ }
+
+ private void InitializeAppState()
+ {
+ // Load features and plugins into the tree view
FeatureNodeManager.LoadFeatures(treeFeatures);
PluginManager.LoadPlugins(treeFeatures);
- if (IniStateManager.IsViewSettingEnabled("SETTINGS", "checkSaveToINI"))
- {
- IniStateManager.Load(treeFeatures, this);
- }
+
+ // Load settings from INI file if enabled
+ IniStateManager.LoadFeaturesIfEnabled(treeFeatures);
}
- private void MainForm_Shown(object sender, EventArgs e)
+ private async Task InitializeUI()
{
- InitializeUI();
- }
+ // Initialize the navigation handler with buttons
+ _navigationHandler = new NavigationHandler(btnFixer, btnRestore, btnTools, btnGitHub);
- private void InitializeUI()
- {
- // Set the default active button
- _navigationHandler = new NavigationHandler(btnHome, btnSettings);
- _navigationHandler.NavigationButtonClicked += button =>
- {
- if (button == btnHome)
- {
- _navigationManager.GoToMain();
- }
- else if (button == btnSettings)
- {
- _navigationManager.SwitchView(new OptionsView());
- }
- };
+ // Load navigation icons
+ await _navigationHandler.LoadNavigationIcons();
- // Set up link label for update check
- linkUpdateCheck.LinkClicked += (_, __) =>
- Process.Start($"https://builtbybel.github.io/CrapFixer/update-check.html?version={Program.GetAppVersion()}");
+ // Register navigation handler
+ _navigationHandler.NavigationButtonClicked += NavigationHandler_NavigationButtonClicked;
- // Set up log actions controller
+ // Register click handlers for GitHub links
+ pictureHeader.Click += PictureHeader_Click;
+ lblHeader.Click += PictureHeader_Click;
+
+ // Re-initialize log actions controller (optional if not changed)
_logActionsController = new LogActionsController(comboLogActions, _logActions);
- // Set up version labels
- async Task SetVersionLabels()
+ // Set version and OS info
+ lblVersionInfo.Text = $"v{Program.GetAppVersion()} ";
+ lblOSInfo.Text = await OSHelper.OSHelper.GetWindowsVersion();
+ }
+
+ // Handles navigation button clicks and switches views accordingly
+ private void NavigationHandler_NavigationButtonClicked(Button button)
+ {
+ if (button == btnFixer)
{
- lblVersionInfo.Text = $"v{Program.GetAppVersion()} ";
- lblOSInfo.Text = await OSHelper.OSHelper.GetWindowsVersion();
+ _navigationManager.GoToMain();
+ }
+ else if (button == btnTools)
+ {
+ _navigationManager.SwitchView(new OptionsView());
}
- _ = SetVersionLabels();
}
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);
- }
+ await PluginManager.AnalyzeAllPlugins(treeFeatures.Nodes);
// Analyze apps
await AnalyzeApps();
@@ -99,40 +102,35 @@ namespace CrapFixer
///
/// Analyzes the apps and logs the results.
///
- ///
private async Task AnalyzeApps()
{
checkedListBoxApps.Items.Clear();
- // Try loading external bloatware list from file
- string[] predefined = _appManager.LoadExternalBloatwareList();
+ // Try loading patterns from CFEnhancer.txt (located in Plugins folder)
+ var (bloatwarePatterns, whitelistPatterns, scanAll) = _appManager.LoadExternalBloatwarePatterns();
- if (predefined.Length == 0)
+ if (bloatwarePatterns.Length == 0 && !scanAll)
{
- // Fallback to internal resource if external file not found or empty
- predefined = Resources.PredefinedApps?
+ // Fallback to internal resource if external file not found or empty and scanAll is not enabled
+ bloatwarePatterns = Resources.PredefinedApps?
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
- .Select(s => s.Trim()).ToArray() ?? Array.Empty();
+ .Select(s => s.Trim().ToLower()).ToArray() ?? Array.Empty();
- // Logger.Log("Using built-in bloatware list.", LogLevel.Info);
+ whitelistPatterns = Array.Empty();
+ Logger.Log("Using built-in bloatware list.", LogLevel.Info);
}
else
{
- Logger.Log("Using external bloatware list via CFEnhancer", LogLevel.Info);
+ Logger.Log("🔎 Plugin ready: CFEnhancer (external bloatware list)", LogLevel.Info);
}
- // Analyze installed apps against the predefined list
- var apps = await _appManager.AnalyzeAndLogAppsAsync(predefined);
+ // Analyze installed apps based on patterns and whitelist, and optionally scan all
+ var apps = await _appManager.AnalyzeAndLogAppsAsync(bloatwarePatterns, whitelistPatterns, scanAll);
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)
@@ -182,53 +180,64 @@ namespace CrapFixer
}
}
+ ///
+ /// Analyzes all plugins and features starting from the selected node from the context menu.
+ ///
private async void analyzeMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
- if (PluginManager.IsPluginNode(selectedNode))
+ Logger.Log($"🔎 Analyzing Feature: {selectedNode.Text}", LogLevel.Info);
+
+ // If a single node is selected (leaf node with no children),
+ // always analyze this node regardless of its Checked state.
+ if (selectedNode.Nodes.Count == 0)
+ {
await PluginManager.AnalyzePlugin(selectedNode);
+ }
else
- Logger.Log($"🔎 Analyzing Feature: {selectedNode.Text}", LogLevel.Info);
+ {
+ // If a parent node is selected (has children),
+ // recursively analyze only the checked plugin nodes.
+ await PluginManager.AnalyzeAll(selectedNode);
+ }
+
+ // Perform feature-specific analysis (non-plugin)
FeatureNodeManager.AnalyzeFeature(selectedNode);
}
}
- private async void previewMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
- {
- if (treeFeatures.SelectedNode is TreeNode selectedNode)
- {
- if (PluginManager.IsPluginNode(selectedNode))
- {
- await PluginManager.AnalyzePlugin(selectedNode);
- }
- else
- {
- FeatureNodeManager.PreviewChanges(selectedNode);
- }
- }
- }
-
+ ///
+ /// Fixes all checked plugin and feature nodes starting from the selected node from the context menu.
+ ///
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);
+ Logger.Log($"🔧 Fixing Feature: {selectedNode.Text}", LogLevel.Info);
+
+ // Recursively fix all checked feature nodes (non-plugin)
await FeatureNodeManager.FixFeature(selectedNode);
+
+ // Recursively fix all checked plugin nodes starting from the selected node
+ await PluginManager.FixPlugin(selectedNode);
}
}
- private void restoreMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
+ ///
+ /// Restores the selected plugin or feature to its previous state from the context menu.
+ ///
+ private async void restoreMarkedFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeFeatures.SelectedNode is TreeNode selectedNode)
{
if (PluginManager.IsPluginNode(selectedNode))
- PluginManager.RestorePlugin(selectedNode);
+ // Restore the plugin using its Undo command if available!
+ await PluginManager.RestorePlugin(selectedNode);
else
Logger.Log($"↩️ Restoring Feature: {selectedNode.Text}", LogLevel.Info);
+
+ // Perform feature-specific restore (non-plugin)
FeatureNodeManager.RestoreFeature(selectedNode);
}
}
@@ -238,18 +247,6 @@ namespace CrapFixer
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);
- }
}
}
@@ -322,26 +319,56 @@ namespace CrapFixer
private void panelHeader_Paint(object sender, PaintEventArgs e)
{
- Panel panel = sender as Panel;
- Graphics g = e.Graphics;
+ var panel = sender as Panel;
+ var g = e.Graphics;
- // Fill background
+ // Solid background: #4D4D4D
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
+ // Inset line effect (3D-like): light line + shadow line
+ Color baseColor = Color.FromArgb(80, 80, 80); // inset base
+
+ using (var topLine = new Pen(ControlPaint.Light(baseColor, 0.0f)))
+ using (var bottomLine = new Pen(ControlPaint.Dark(baseColor, 0.2f)))
{
- int y = panel.Height - 1; // Bottom-most pixel
- g.DrawLine(pen, 0, y, panel.Width, y);
+ g.SmoothingMode = SmoothingMode.None;
+ g.DrawLine(topLine, 0, panel.Height - 2, panel.Width, panel.Height - 2);
+ g.DrawLine(bottomLine, 0, panel.Height - 1, panel.Width, panel.Height - 1);
}
}
+ // Handles click on the header image to open the GitHub page
+ private void PictureHeader_Click(object sender, EventArgs e)
+ {
+ Utils.OpenGitHubPage(sender, e);
+ }
+
+ // Handles link click to check for updates
+ private void linkUpdateCheck_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ var updateUrl = $"https://builtbybel.github.io/CrapFixer/update-check.html?version={Program.GetAppVersion()}";
+
+ var psi = new ProcessStartInfo
+ {
+ FileName = updateUrl,
+ UseShellExecute = true
+ };
+ Process.Start(psi);
+ }
+
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (IniStateManager.IsViewSettingEnabled("SETTINGS", "checkSaveToINI"))
{
IniStateManager.Save(treeFeatures, this);
}
+
+ Logger.OutputBox = null; // Remove reference
+ }
+
+ private void btnGitHub_Click(object sender, EventArgs e)
+ {
+ _navigationManager.SwitchView(new OptionsView());
}
}
}
\ No newline at end of file
diff --git a/CFixer/MainForm.resx b/CFixer/MainForm.resx
index bfbb24f..3639ac6 100644
--- a/CFixer/MainForm.resx
+++ b/CFixer/MainForm.resx
@@ -120,339 +120,10 @@
23, 15
-
-
-
- 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
- AABJRU5ErkJggg==
-
-
+
+ 171, 15
+
+
+ 171, 15
+
\ No newline at end of file
diff --git a/CFixer/NavigationHandler.cs b/CFixer/NavigationHandler.cs
index 8010d36..7b9477c 100644
--- a/CFixer/NavigationHandler.cs
+++ b/CFixer/NavigationHandler.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.IO;
+using System.Threading.Tasks;
using System.Windows.Forms;
namespace CFixer
@@ -13,14 +15,14 @@ namespace CFixer
// List of all buttons managed by the navigation handler
private readonly List