using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.Loader; using System.Text; using System.Threading.Tasks; namespace LB_VisionProcesses { public class PluginManager { private static readonly List _loadedAssemblies = new List(); private static readonly Dictionary _loadContexts = new Dictionary(); private static readonly object _lock = new object(); /// /// 已加载的工具字典(键:显示名称,值:类型完全限定名) /// public static Dictionary LoadedProcesses { get; } = new Dictionary(); /// /// 按分类组织的工具 /// public static Dictionary> CategorizedProcesses { get; } = new Dictionary>(); /// /// 插件信息 /// public static List PluginInfos { get; } = new List(); /// /// 插件目录路径 /// public static string PluginDirectory { get; set; } = "Plugins"; /// /// 插件加载事件 /// public static event EventHandler PluginLoaded; public static event EventHandler PluginUnloaded; static PluginManager() { // 确保插件目录存在 if (!Directory.Exists(PluginDirectory)) { Directory.CreateDirectory(PluginDirectory); } } /// /// 加载所有插件 /// public static void LoadAllPlugins() { lock (_lock) { ClearLoadedAssemblies(); // 加载主程序集的工具 ScanAssemblyForProcesses(Assembly.GetExecutingAssembly(), "LB_VisionProcesses"); // 加载插件目录的DLL LoadAssembliesFromDirectory(PluginDirectory); // 加载配置文件指定的插件 LoadFromConfig(); } } /// /// 加载指定程序集 /// public static bool LoadAssembly(string assemblyPath, string pluginName = null) { lock (_lock) { try { if (!File.Exists(assemblyPath)) { Debug.WriteLine($"程序集文件不存在: {assemblyPath}"); return false; } // 检查是否已加载 var fileName = Path.GetFileName(assemblyPath); if (_loadContexts.ContainsKey(fileName)) { Debug.WriteLine($"程序集已加载: {fileName}"); return false; } // 创建隔离的加载上下文 var context = new PluginLoadContext(assemblyPath); var assembly = context.LoadFromAssemblyPath(assemblyPath); _loadedAssemblies.Add(assembly); _loadContexts[fileName] = context; // 扫描工具类 var pluginInfo = ScanAssemblyForProcesses(assembly, pluginName ?? Path.GetFileNameWithoutExtension(assemblyPath)); PluginInfos.Add(pluginInfo); // 触发事件 PluginLoaded?.Invoke(null, new PluginEventArgs(pluginInfo)); return true; } catch (Exception ex) { Debug.WriteLine($"加载程序集失败: {assemblyPath}, 错误: {ex.Message}"); return false; } } } /// /// 加载指定目录下所有DLL /// public static void LoadAssembliesFromDirectory(string directoryPath) { if (!Directory.Exists(directoryPath)) { Debug.WriteLine($"插件目录不存在: {directoryPath}"); return; } // 加载主DLL var dllFiles = Directory.GetFiles(directoryPath, "*.dll") .Where(f => !f.EndsWith(".resources.dll") && !f.Contains("\\ref\\") && !Path.GetFileName(f).StartsWith("System.") && !Path.GetFileName(f).StartsWith("Microsoft.")) .ToList(); // 先加载没有依赖的,再加载可能有依赖的 var orderedFiles = dllFiles.OrderBy(f => File.ReadAllBytes(f).Length).ToList(); // 按文件大小排序,小的先加载 foreach (var dllFile in orderedFiles) { try { LoadAssembly(dllFile); } catch (Exception ex) { Debug.WriteLine($"加载DLL失败: {dllFile}, 错误: {ex.Message}"); } } } /// /// 卸载指定插件 /// public static bool UnloadPlugin(string pluginName) { lock (_lock) { var pluginInfo = PluginInfos.FirstOrDefault(p => p.Name == pluginName); if (pluginInfo == null) return false; try { // 从工具字典中移除 foreach (var process in pluginInfo.Processes) { LoadedProcesses.Remove(process.Key); // 从分类字典中移除 if (CategorizedProcesses.ContainsKey(process.Value.Category)) { CategorizedProcesses[process.Value.Category].Remove(process.Key); } } // 触发事件 PluginUnloaded?.Invoke(null, new PluginEventArgs(pluginInfo)); // 从列表中移除 PluginInfos.Remove(pluginInfo); // 尝试卸载程序集(需要.NET Core 3.0+) var fileName = Path.GetFileName(pluginInfo.AssemblyPath); if (_loadContexts.TryGetValue(fileName, out var context)) { _loadContexts.Remove(fileName); if (context.IsCollectible) { context.Unload(); } } return true; } catch (Exception ex) { Debug.WriteLine($"卸载插件失败: {pluginName}, 错误: {ex.Message}"); return false; } } } /// /// 扫描程序集中的工具类 /// private static PluginInfo ScanAssemblyForProcesses(Assembly assembly, string pluginName) { var pluginInfo = new PluginInfo { Name = pluginName, AssemblyPath = assembly.Location, Version = assembly.GetName().Version?.ToString() ?? "1.0.0", LoadedTime = DateTime.Now }; try { var processTypes = assembly.GetTypes() .Where(t => t.IsClass && !t.IsAbstract && typeof(IProcess).IsAssignableFrom(t)) .ToList(); foreach (var type in processTypes) { try { if (type.IsDefined(typeof(ProcessAttribute), false) || type.IsDefined(typeof(CategoryAttribute), false)) { // 使用特性获取元数据,避免实例化 var processAttr = type.GetCustomAttribute(); var categoryAttr = type.GetCustomAttribute(); string displayName; string category = "其他"; string description = ""; int order = 0; if (processAttr != null) { displayName = processAttr.DisplayName; category = processAttr.Category; description = processAttr.Description; order = processAttr.Order; } else { // 如果没有特性,使用类型名称 displayName = type.Name; } if (categoryAttr != null) { category = categoryAttr.Category; } // 避免重复名称 int suffix = 1; string originalName = displayName; while (LoadedProcesses.ContainsKey(displayName)) { displayName = $"{originalName}_{suffix}"; suffix++; } string fullName = type.AssemblyQualifiedName; // 添加到总字典 LoadedProcesses[displayName] = fullName; // 按分类组织 if (!CategorizedProcesses.ContainsKey(category)) { CategorizedProcesses[category] = new Dictionary(); } CategorizedProcesses[category][displayName] = fullName; // 添加到插件信息 pluginInfo.Processes[displayName] = new ProcessInfo { TypeName = fullName, DisplayName = displayName, Category = category, Description = description, Order = order }; Debug.WriteLine($"注册工具: {displayName} ({category})"); } } catch (Exception ex) { Debug.WriteLine($"注册工具类型 {type.Name} 失败: {ex.Message}"); } } } catch (ReflectionTypeLoadException ex) { Debug.WriteLine($"扫描程序集 {assembly.FullName} 时类型加载失败: {ex.Message}"); foreach (var loaderEx in ex.LoaderExceptions) { Debug.WriteLine($"加载异常: {loaderEx?.Message}"); } } catch (Exception ex) { Debug.WriteLine($"扫描程序集 {assembly.FullName} 失败: {ex.Message}"); } return pluginInfo; } /// /// 从配置文件加载插件 /// private static void LoadFromConfig() { var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugin.config.json"); if (File.Exists(configPath)) { try { var config = File.ReadAllText(configPath); var pluginConfigs = JsonConvert.DeserializeObject>(config); foreach (var pluginConfig in pluginConfigs) { if (pluginConfig.Enabled) { var pluginPath = Path.Combine(PluginDirectory, pluginConfig.AssemblyName); LoadAssembly(pluginPath, pluginConfig.Name); } } } catch (Exception ex) { Debug.WriteLine($"读取插件配置失败: {ex.Message}"); } } } /// /// 清空已加载的程序集 /// private static void ClearLoadedAssemblies() { lock (_lock) { _loadedAssemblies.Clear(); _loadContexts.Clear(); LoadedProcesses.Clear(); CategorizedProcesses.Clear(); PluginInfos.Clear(); } } /// /// 重新加载所有插件 /// public static void ReloadPlugins() { lock (_lock) { ClearLoadedAssemblies(); LoadAllPlugins(); } } /// /// 获取所有分类 /// public static List GetCategories() { return CategorizedProcesses.Keys.OrderBy(k => k).ToList(); } /// /// 获取指定分类的工具 /// public static Dictionary GetProcessesByCategory(string category) { return CategorizedProcesses.ContainsKey(category) ? CategorizedProcesses[category] : new Dictionary(); } /// /// 创建工具实例 /// public static IProcess CreateProcess(string displayName) { lock (_lock) { if (!LoadedProcesses.TryGetValue(displayName, out string typeName)) { throw new KeyNotFoundException($"未找到工具: {displayName}"); } try { var type = Type.GetType(typeName); if (type == null) { // 尝试从已加载的程序集中查找 foreach (var assembly in _loadedAssemblies) { type = assembly.GetType(typeName.Split(',')[0]); if (type != null) break; } } if (type == null) { throw new TypeLoadException($"无法加载类型: {typeName}"); } return Activator.CreateInstance(type) as IProcess; } catch (Exception ex) { throw new ApplicationException($"创建工具实例失败: {displayName}", ex); } } } } }