///*************************************************************************/
|
///*
|
///* 文件名 :ModuleLoader.cs
|
///* 程序说明 : 模块加载器
|
///* 原创作者 :孙中吕
|
///*
|
///* Copyright 2006-2021 C/S框架网 www.csframework.com
|
///*
|
///**************************************************************************/
|
|
using System;
|
using System.Collections.Generic;
|
using System.Data;
|
using System.IO;
|
using System.Reflection;
|
using System.Windows.Forms;
|
|
namespace CSFrameworkV5.Core
|
{
|
#region 模块加载器
|
|
/// <summary>
|
/// 模块加载器基类
|
/// </summary>
|
public class ModuleLoaderBase
|
{
|
/// <summary>
|
/// 模块文件名(DLL文件)
|
/// </summary>
|
protected string _ModuleFileName;
|
|
/// <summary>
|
/// 如果加载了模块,返回该模块的主窗体对象.
|
/// </summary>
|
protected IModuleBase _ModuleMainForm;
|
|
/// <summary>
|
/// 模块所在的程序集
|
/// </summary>
|
protected Assembly _ModuleAssembly;
|
|
/// <summary>
|
/// 模块所在的程序集
|
/// </summary>
|
public Assembly ModuleAssembly => _ModuleAssembly;
|
|
/// <summary>
|
/// 返回当前模块的名称,从AssemblyModuleEntry自定义特性内获取信息。
|
/// </summary>
|
public string GetCurrentModuleName(Assembly asm)
|
{
|
return GetModuleEntry(asm).ModuleName;
|
}
|
|
/// <summary>
|
/// 模块主窗体
|
/// </summary>
|
public IModuleBase ModuleMainForm => _ModuleMainForm;
|
|
/// <summary>
|
/// 加载模块的菜单(支持一个模块内有多个顶级菜单)
|
/// </summary>
|
/// <param name="menuStrip">程序主窗体的菜单</param>
|
public virtual void LoadMenu(MenuStrip moduleMenus)
|
{
|
var moduleMenu = _ModuleMainForm.GetModuleMenu(); //当前模块的菜单
|
if (moduleMenu == null || moduleMenu.Items.Count == 0) return;
|
|
if (_ModuleMainForm != null)
|
while (moduleMenu.Items.Count > 0) //加载所有顶级菜单
|
{
|
var startIndex = moduleMenus.Items.Count == 0
|
? 0
|
: moduleMenus.Items.Count;
|
moduleMenus.Items.Insert(startIndex, moduleMenu.Items[0]);
|
}
|
}
|
|
/// <summary>
|
/// 加载模块主窗体
|
/// </summary>
|
/// <param name="moduleinfo">模块信息</param>
|
/// <returns></returns>
|
public virtual bool LoadModule(ModuleInfo moduleinfo)
|
{
|
_ModuleMainForm = null;
|
_ModuleFileName = moduleinfo.ModuleFile;
|
_ModuleAssembly = moduleinfo.ModuleAssembly;
|
|
//获取模块主窗体的命名空间
|
var entry = GetModuleEntryNameSpace(_ModuleAssembly);
|
if (string.Empty == entry) return false;
|
|
var form = (Form)_ModuleAssembly.CreateInstance(entry);
|
if (form is IModuleBase) _ModuleMainForm = (IModuleBase)form;
|
return _ModuleMainForm != null;
|
}
|
|
/// <summary>
|
/// 枚举主程序所在目录下所有DLL文件,获取业务模块列表并转换为ModuleInfo集合.
|
/// </summary>
|
/// <param name="searchPattern">查找的文件扩展名</param>
|
/// <returns></returns>
|
public virtual IList<ModuleInfo> GetModuleList(string searchPattern)
|
{
|
IList<ModuleInfo> list = new List<ModuleInfo>();
|
|
try
|
{
|
var files = new string[] { }; //模块文件(*.dll)
|
var root = Application.StartupPath;
|
|
if (Directory.Exists(root))
|
files = Directory.GetFiles(root, searchPattern);
|
|
//for test
|
//File.WriteAllText(@"c:\cstest.txt", root + " " + searchPattern);
|
|
//枚举所有文件
|
foreach (var mod in files)
|
{
|
Assembly asm = null;
|
try
|
{
|
//加载.Net Framework DLL文件
|
asm = Assembly.LoadFile(mod);
|
}
|
catch
|
{
|
continue;
|
}
|
|
var id = GetModuleID(asm);
|
var name = GetCurrentModuleName(asm);
|
if (id != 0)
|
{
|
var m = new ModuleInfo(asm, id, name, mod);
|
list.Add(m);
|
}
|
}
|
|
SortModule(list); //模块排序.
|
|
return list;
|
}
|
catch (Exception ex)
|
{
|
return list;
|
}
|
}
|
|
/// <summary>
|
/// 模块排序
|
/// </summary>
|
/// <param name="list"></param>
|
public virtual void SortModule(IList<ModuleInfo> list)
|
{
|
int i = 0, j = 1;
|
ModuleInfo temp;
|
var done = false;
|
while (j < list.Count && !done)
|
{
|
done = true;
|
for (i = 0; i < list.Count - j; i++)
|
if ((list[i] as ModuleInfo).ModuleID >
|
(list[i + 1] as ModuleInfo).ModuleID)
|
{
|
done = false;
|
temp = list[i];
|
list[i] = list[i + 1];
|
list[i + 1] = temp;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 将数据库获取的模块列表转换为ModuleInfo集合.
|
/// </summary>
|
/// <param name="fileList">数据库获取的模块列表</param>
|
/// <returns></returns>
|
public virtual IList<ModuleInfo> GetModuleList(DataTable fileList)
|
{
|
IList<ModuleInfo> moduleList = new List<ModuleInfo>();
|
try
|
{
|
var file = ""; //模块文件(*.dll)
|
var rs =
|
fileList.Select(" IsVisible='Y' ", " SortID ASC"); //模块可用和排序
|
foreach (var R in rs)
|
{
|
//检查文件是否存在
|
file = Application.StartupPath + "\\" +
|
R["FileName"].ToStringEx();
|
if (!File.Exists(file)) continue;
|
|
Assembly asm = null;
|
try
|
{
|
asm = Assembly.LoadFile(file);
|
}
|
catch
|
{
|
continue;
|
}
|
|
var id = GetModuleID(asm);
|
var name = GetCurrentModuleName(asm);
|
if (id != 0)
|
{
|
var m = new ModuleInfo(asm, id, name, file);
|
moduleList.Add(m);
|
}
|
}
|
|
return moduleList;
|
}
|
catch (Exception ex)
|
{
|
return moduleList;
|
}
|
}
|
|
/// <summary>
|
/// 获取程序集的自定义特性。
|
/// </summary>
|
/// <returns></returns>
|
public AssemblyModuleEntry GetModuleEntry()
|
{
|
return GetModuleEntry(_ModuleAssembly);
|
}
|
|
/// <summary>
|
/// 通过检查Assembly定义的特性AssemblyModuleEntry,判断加载的文件是否业务模块文件。
|
/// 程序目录有不同类别的DLL文件,若没有定义AssemblyModuleEntry特性即不是业务模块。
|
/// </summary>
|
public bool IsModuleFile(string moduleFile)
|
{
|
try
|
{
|
var asm = Assembly.LoadFile(moduleFile);
|
return GetModuleID(asm) != 0;
|
}
|
catch
|
{
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// 每个业务模块的主窗体定义一个TabPage与Panel, 将模块主窗体的Panel组件嵌套在主窗体的TabPage内。
|
/// </summary>
|
public virtual void LoadGUI(object mainTabControl)
|
{
|
}
|
|
#region 类公共静态方法
|
|
/// <summary>
|
/// 查找子菜单,深度搜索
|
/// </summary>
|
public static ToolStripMenuItem GetMenuItem(ToolStrip mainMenu,
|
string menuName)
|
{
|
var items = mainMenu.Items.Find(menuName, true);
|
if (items.Length > 0 && items[0] is ToolStripMenuItem)
|
return (ToolStripMenuItem)items[0];
|
else
|
return null;
|
}
|
|
/// <summary>
|
/// 获取程序集自定义特性。是否用户自定义模块由AssemblyModuleEntry特性确定。
|
/// </summary>
|
public static AssemblyModuleEntry GetModuleEntry(Assembly asm)
|
{
|
var temp = new AssemblyModuleEntry(0, "", "");
|
if (asm == null) return temp;
|
|
var list =
|
asm.GetCustomAttributes(typeof(AssemblyModuleEntry), false);
|
if (list.Length > 0)
|
return (AssemblyModuleEntry)list[0];
|
else
|
return temp;
|
}
|
|
/// <summary>
|
/// 获取模块主窗体名字空间
|
/// </summary>
|
public static string GetModuleEntryNameSpace(Assembly asm)
|
{
|
return GetModuleEntry(asm).ModuleEntryNameSpace;
|
}
|
|
/// <summary>
|
/// 获取模块编号
|
/// </summary>
|
public static int GetModuleID(Assembly asm)
|
{
|
return GetModuleEntry(asm).ModuleID;
|
}
|
|
#endregion
|
|
/// <summary>
|
/// 判断当前用户是否有该模块的权限
|
/// </summary>
|
/// <param name="userRights">用户权限数据</param>
|
/// <returns></returns>
|
public bool CanAccessModule(DataTable userRights)
|
{
|
//管理员例外
|
if (Loginer.CurrentUser.IsAdmin()) return true;
|
|
var mainMenu = _ModuleMainForm.GetModuleMenu();
|
var rows = userRights.Select(string.Format("MenuName='{0}'",
|
mainMenu.Items[0].Name));
|
return rows != null && rows.Length > 0;
|
}
|
|
/// <summary>
|
/// 程序集对象引用置空,优化GC回收内存
|
/// </summary>
|
public void ClearAssemble()
|
{
|
_ModuleAssembly = null;
|
_ModuleMainForm = null;
|
}
|
}
|
|
#endregion
|
}
|