| | |
| | | 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; |
| | |
| | | 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() |
| | |
| | | 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)) |
| | |
| | | } |
| | | 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 |
| | | { |
| | |
| | | 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()); |
| | |
| | | { |
| | | Code = dr["code"].ToString(), |
| | | Name = dr["name"].ToString(), |
| | | Type = dr["type"].ToString(), |
| | | ParentCode = dr["parentCode"].ToString(), |
| | | DllPath = dr["dllPath"].ToString(), |
| | | ClassName = dr["className"].ToString(), |