using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.IO; using System.Reflection; using System.Windows.Media.Imaging; using HMI.Core.Api; using HMI.Core.Util; using log4net; namespace HMI.Base { public class PluginLoader { private static string PluginFolder = PathHelper.PluginFolder(); public bool Completed { get; private set; } = false; public SqliteHelper sqliteHelper; public ObservableCollection Menus { get; private set; } public ObservableCollection Plugins { get; private set; } public static PluginLoader Instance { get; private set; } public event EventHandler LoadMessageAppend; private PluginLoader() { sqliteHelper = new SqliteHelper(PathHelper.DatabasePath); } public static PluginLoader GetLoader() { if (Instance == null) { Instance = new PluginLoader(); } return Instance; } public void LoadMenuAndPlugin() { if (Menus == null) { Plugins = new ObservableCollection(); Menus = LoadTreeMenu(); } } private void LoadChildrenMenu(PluginInfo menu) { LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单..."); try { if (!string.IsNullOrEmpty(menu.DllPath)) { string dllPath = Path.Combine(PluginFolder, menu.DllPath); Assembly ass = Assembly.LoadFrom(dllPath); Type ClassType = ass.GetType(menu.ClassName); object Instance = Activator.CreateInstance(ClassType); menu.Content = Instance; if (Instance is IPlugin plugin) { plugin.SetLogger(LogManager.GetLogger(menu.Code)); string configFolder = Path.Combine(PathHelper.ConfigFolder, menu.Code); if (!Directory.Exists(configFolder)) { Directory.CreateDirectory(configFolder); } plugin.SetBaseFolder(configFolder); plugin.InitFinish(); } Type SettingType = ass.GetType($"{menu.ClassName}_Setting"); if (SettingType != null) { object SettingInstance = Activator.CreateInstance(SettingType); menu.SettingControl = SettingInstance; } } } catch (Exception ex) { LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}"); } } public ObservableCollection LoadTreeMenu() { ObservableCollection data = new ObservableCollection(); Dictionary cache = new Dictionary(); try { LoadMessageAppend?.Invoke(this, "开始加载菜单..."); DataTable dt = sqliteHelper.GetDataTable(@"SELECT * FROM menu ORDER BY level,id;"); if (dt != null) { LoadMessageAppend?.Invoke(this, $"共有{dt.Rows.Count}条菜单待加载..."); foreach (DataRow dr in dt.Rows) { string path = Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString()); var menu = new PluginInfo { Code = dr["code"].ToString(), Name = dr["name"].ToString(), ParentCode = dr["parentCode"].ToString(), DllPath = dr["dllPath"].ToString(), ClassName = dr["className"].ToString(), Icon = new BitmapImage(new Uri(Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString()))) }; cache[menu.Code] = menu; if (!cache.ContainsKey(menu.ParentCode)) { data.Add(menu); } else { cache[menu.ParentCode].Children.Add(menu); } Plugins.Add(menu); LoadChildrenMenu(menu); } } } catch (Exception ex) { LoadMessageAppend?.Invoke(this, ex.Message); } return data; } } }