alielie
2025-03-28 dedcf4174c8540ee3a912daad2ff13e014e495b1
HMI.Base/PluginLoader.cs
@@ -8,15 +8,27 @@
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 enum LoadMsgType
    {
        INIT, LOADING, FINISHED
    }
    public class LoadMsg
    {
        public string Message { get; set; }
        public bool? Result { get; set; }
        public LoadMsgType Type { get; set; }
        public int NumData { get; set; }
    }
    public class PluginLoader
    {
        private static ILog log = LogManager.GetLogger("PluginLoader");
        private static string PluginFolder = PathHelper.PluginFolder();
        public bool Completed { get; private set; } = false;
@@ -25,12 +37,19 @@
        public List<PluginInfo> Plugins { get; private set; }
        public static PluginLoader Instance { get; private set; }
        public event EventHandler<string> LoadMessageAppend;
        public event EventHandler Loaded;
        public event EventHandler<LoadMsg> LoadMessageAppend;
        private PluginLoader()
        {
            sqliteHelper = new SqliteHelper(PathHelper.DatabasePath);
        }
        public static void Reset()
        {
            if (Instance != null)
            {
                Instance = null;
            }
        }
        public static PluginLoader GetLoader()
@@ -42,32 +61,53 @@
            return Instance;
        }
        public void LoadMenuAndPlugin(Dispatcher dispatcher)
        private IPluginContainer pluginContainer;
        public void LoadMenuAndPlugin(IPluginContainer container, Dispatcher dispatcher)
        {
            pluginContainer = container;
            if (Menus == null)
            {
                Plugins = new List<PluginInfo>();
                Menus = LoadTreeMenu(dispatcher);
                Loaded?.Invoke(this, null);
                sqliteHelper.Close();
                dispatcher.Invoke(() =>
                {
                    LoadMessageAppend?.Invoke(this, new LoadMsg { Type = LoadMsgType.FINISHED });
                });
            }
        }
        private void LoadChildrenMenu(PluginInfo menu, Dispatcher dispatcher)
        private void LoadChildrenMenu()
        {
            LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单...");
            try
            foreach (var menu in Plugins)
            {
                Application.Current.Dispatcher.Invoke(() =>
                CountdownEvent c = new CountdownEvent(1);
                Thread.Sleep(80);
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    if (!string.IsNullOrEmpty(menu.DllPath))
                    try
                    {
                        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)
                        LoadMessageAppend?.Invoke(this,
                            new LoadMsg
                            {
                                Type = LoadMsgType.LOADING,
                                Message = this.lang("App.IsLoadingMenu", menu.Name)
                            }
                        );
                        if (!string.IsNullOrEmpty(menu.DllPath))
                        {
                            string dllPath = Path.Combine(PluginFolder, menu.DllPath);
                            Assembly ass = Assembly.LoadFrom(dllPath);
                            var tss = ass.GetTypes();
                            Type ClassType = ass.GetType(menu.ClassName);
                            object Instance = Activator.CreateInstance(ClassType);
                            menu.Content = Instance;
                            if (Instance is IPlugin plugin)
                            {
                            }
                            else
                            {
                                plugin = new PluginPackage(Instance);
                            }
                            plugin.SetLogger(LogManager.GetLogger(menu.Code));
                            string configFolder = Path.Combine(PathHelper.ConfigFolder, menu.Code);
                            if (!Directory.Exists(configFolder))
@@ -76,69 +116,36 @@
                            }
                            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)
                            pluginContainer.OnCloseEvent += plugin.OnClose;
                            pluginContainer.DoCloseEvent += plugin.DoClose;
                            Type SettingType = ass.GetType($"{menu.ClassName}_Setting");
                            if (SettingType != null)
                            {
                                plugin.SetLogger(LogManager.GetLogger(menu.Code));
                                string configFolder = Path.Combine(PathHelper.ConfigFolder, menu.Code);
                                if (!Directory.Exists(configFolder))
                                object SettingInstance = Activator.CreateInstance(SettingType);
                                if (SettingInstance is IFolderOwner fo)
                                {
                                    Directory.CreateDirectory(configFolder);
                                    fo.SetBaseFolder(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;
                                }
                                menu.SettingControl = SettingInstance;
                            }
                        }
                        LoadMessageAppend?.Invoke(this, $"加载完");
                        LoadMessageAppend?.Invoke(this,
                            new LoadMsg
                            {
                                Type = LoadMsgType.LOADING,
                                Result = true,
                                Message = this.lang("App.MenuLoadSuccess", menu.Name),
                            });
                    }
                    catch (Exception ex)
                    {
                        LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}");
                        log.Error("Load Plugin Failed.", ex);
                        LoadMessageAppend?.Invoke(this, new LoadMsg
                        {
                            Type = LoadMsgType.LOADING,
                            Result = false,
                            Message = this.lang("App.MenuLoadFailed", menu.Name, ex.Message, ex.StackTrace)
                        });
                    }
                    finally
                    {
@@ -160,14 +167,21 @@
                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;";
AND urel.username = '{user.Username}' ORDER BY m.level,m.sort, m.id;";
                DataTable dt = sqliteHelper.GetDataTable(sql);
                if (dt != null)
                {
                    //LoadMessageAppend?.Invoke(this, $"共有{dt.Rows.Count}条菜单待加载...");
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        LoadMessageAppend?.Invoke(this,
                          new LoadMsg
                          {
                              Type = LoadMsgType.INIT,
                              NumData = dt.Rows.Count,
                              Message = this.lang("App.MenuCount", dt.Rows.Count),
                          });
                        foreach (DataRow dr in dt.Rows)
                        {
                            string path = Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString());
@@ -175,6 +189,7 @@
                            {
                                Code = dr["code"].ToString(),
                                Name = dr["name"].ToString(),
                                Type = dr["type"].ToString(),
                                ParentCode = dr["parentCode"].ToString(),
                                DllPath = dr["dllPath"].ToString(),
                                ClassName = dr["className"].ToString(),