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.Windows;
|
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 SqliteHelper sqliteHelper;
|
public List<PluginInfo> Menus { get; private set; }
|
public List<PluginInfo> Plugins { get; private set; }
|
public static PluginLoader Instance { get; private set; }
|
|
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()
|
{
|
if (Instance == null)
|
{
|
Instance = new PluginLoader();
|
}
|
return Instance;
|
}
|
|
private IPluginContainer pluginContainer;
|
|
public void LoadMenuAndPlugin(IPluginContainer container, Dispatcher dispatcher)
|
{
|
pluginContainer = container;
|
if (Menus == null)
|
{
|
Plugins = new List<PluginInfo>();
|
Menus = LoadTreeMenu(dispatcher);
|
sqliteHelper.Close();
|
dispatcher.Invoke(() =>
|
{
|
LoadMessageAppend?.Invoke(this, new LoadMsg { Type = LoadMsgType.FINISHED });
|
});
|
}
|
}
|
|
private void LoadChildrenMenu()
|
{
|
foreach (var menu in Plugins)
|
{
|
CountdownEvent c = new CountdownEvent(1);
|
Thread.Sleep(80);
|
Application.Current.Dispatcher.Invoke(new Action(() =>
|
{
|
try
|
{
|
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))
|
{
|
Directory.CreateDirectory(configFolder);
|
}
|
plugin.SetBaseFolder(configFolder);
|
plugin.InitFinish();
|
pluginContainer.OnCloseEvent += plugin.OnClose;
|
pluginContainer.DoCloseEvent += plugin.DoClose;
|
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,
|
new LoadMsg
|
{
|
Type = LoadMsgType.LOADING,
|
Result = true,
|
Message = this.lang("App.MenuLoadSuccess", menu.Name),
|
});
|
}
|
catch (Exception ex)
|
{
|
log.Error($"Load Plugin [{menu.Name}] Failed.", ex);
|
LoadMessageAppend?.Invoke(this, new LoadMsg
|
{
|
Type = LoadMsgType.LOADING,
|
Result = false,
|
Message = this.lang("App.MenuLoadFailed", menu.Name, ex.Message, ex.StackTrace)
|
});
|
}
|
finally
|
{
|
c.Signal();
|
}
|
}));
|
c.Wait();
|
}
|
}
|
|
public List<PluginInfo> LoadTreeMenu(Dispatcher dispatcher)
|
{
|
//LoadMessageAppend?.Invoke(this, "开始加载菜单...");
|
List<PluginInfo> data = new List<PluginInfo>();
|
Dictionary<string, PluginInfo> cache = new Dictionary<string, PluginInfo>();
|
try
|
{
|
UserInfo user = UserInfo.User;
|
string sql = $@"SELECT DISTINCT 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.sort, m.id;";
|
|
DataTable dt = sqliteHelper.GetDataTable(sql);
|
if (dt != null)
|
{
|
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());
|
var menu = new PluginInfo
|
{
|
Code = dr["code"].ToString(),
|
Name = dr["name"].ToString(),
|
Type = dr["type"].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;
|
}
|
}
|
}
|