using HMI.Core.Api; using HMI.Core.Entity; using HMI.Core.Util; using log4net; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Reflection; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Media.Imaging; using System.Windows.Threading; namespace HMI.Base { public class PluginLoader { private static string PluginFolder = PathHelper.PluginFolder(); public bool Completed { get; private set; } = false; public SqliteHelper sqliteHelper; public List Menus { get; private set; } public List Plugins { get; private set; } public static PluginLoader Instance { get; private set; } public event EventHandler LoadMessageAppend; public event EventHandler Loaded; private PluginLoader() { sqliteHelper = new SqliteHelper(PathHelper.DatabasePath); } public static PluginLoader GetLoader() { if (Instance == null) { Instance = new PluginLoader(); } return Instance; } public void LoadMenuAndPlugin(Dispatcher dispatcher) { if (Menus == null) { Plugins = new List(); Menus = LoadTreeMenu(dispatcher); Loaded?.Invoke(this, null); } } private void LoadChildrenMenu(PluginInfo menu, Dispatcher dispatcher) { LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单..."); try { Application.Current.Dispatcher.Invoke(() => { 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; } } }); Thread.Sleep(100); } catch (Exception ex) { LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}"); } } private void LoadChildrenMenu() { foreach (var menu in Plugins) { CountdownEvent c = new CountdownEvent(1); Thread.Sleep(10); Application.Current.Dispatcher.Invoke(new Action(() => { try { LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单..."); 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); if (SettingInstance is IFolderOwner fo) { fo.SetBaseFolder(configFolder); } menu.SettingControl = SettingInstance; } } } LoadMessageAppend?.Invoke(this, $"加载完"); } catch (Exception ex) { LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}"); } finally { c.Signal(); } })); c.Wait(); } } public List LoadTreeMenu(Dispatcher dispatcher) { //LoadMessageAppend?.Invoke(this, "开始加载菜单..."); List data = new List(); Dictionary cache = new Dictionary(); try { UserInfo user = UserInfo.User; string sql = $@"SELECT m.* FROM menu AS m INNER JOIN role_menu_rel AS rrel ON m.code = rrel.menuCode INNER JOIN role AS r ON rrel.roleCode = r.code INNER JOIN user_role_rel AS urel ON r.code = urel.roleCode AND urel.username = '{user.Username}' ORDER BY m.level, m.id;"; DataTable dt = sqliteHelper.GetDataTable(sql); if (dt != null) { //LoadMessageAppend?.Invoke(this, $"共有{dt.Rows.Count}条菜单待加载..."); Application.Current.Dispatcher.Invoke(() => { 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(), IconFont = dr["icon"].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(); } } catch (Exception ex) { //LoadMessageAppend?.Invoke(this, ex.Message); } return data; } } }