Files
Crapfixer/MSCFixer/PluginManager.cs
T
2025-05-07 19:39:40 +02:00

198 lines
6.5 KiB
C#

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
}
}