📄 pluginmanager.cs
字号:
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Windows.Forms;
using System.Threading;
using Core.Services.Sdk;
namespace Core.Services.Management
{
/// <summary>
/// 提供了一系列功能来辅助插件管理。
/// </summary>
public class PluginManager:IDisposable
{
private Hashtable _Map;
private Hashtable _Type;
private ArrayList _LoadedPlugins;
private Thread _PluginThread;
private ArrayList _Targets;
private ContextMenuStrip _Menu;
private ToolStripMenuItem _menuItem;
private ProgressChangedEventHandler _pce;
private bool _SetBackground=false;
private IPlugin _Current;
private Form _Parent;
/// <summary>
/// 已加载的插件列表
/// </summary>
public ArrayList PluginInfos
{
get
{
return _LoadedPlugins;
}
}
/// <summary>
/// 可用于集成到用户界面的快捷菜单
/// </summary>
public ContextMenuStrip Menu
{
get
{
return _Menu;
}
}
/// <summary>
/// 插件的窗体
/// </summary>
public Form PluginWindow
{
get
{
if (_Current != null)
return _Current.Window;
else
return null;
}
}
/// <summary>
/// 创建一个PluginManager实例并开始插件管理工作
/// </summary>
/// <param name="SearchDirectory">指定PluginManager搜索插件的目录</param>
/// <param name="MenuClickHandler">指定处理插件菜单项Click事件的方法</param>
/// <param name="SetBackground">指定是否将插件工作的线程设为后台线程</param>
/// <param name="ParentWindow">宿主程序的窗体</param>
/// <returns>一个PluginManager的实例</returns>
public PluginManager(string SearchDirectory,bool SetBackground, EventHandler MenuClickHandler,Form ParentWindow)
{
_Map = new Hashtable();
_Type = new Hashtable();
_SetBackground = SetBackground;
_Parent = ParentWindow;
_LoadedPlugins = new ArrayList();
InitializePlugins(SearchDirectory,MenuClickHandler);
}
/// <summary>
/// 为已与菜单项关联的插件分配任务并添加插件事件的处理方法,把插件放入一个后台线程线程开始执行
/// </summary>
/// <param name="menuItem">与插件关联的菜单项</param>
/// <param name="Targets">要处理的对象的文件名或文件夹列表</param>
/// <param name="pce">处理ProgressChanged事件的方法</param>
/// <returns>是否成功地分配了任务</returns>
public bool AssignTask(ToolStripMenuItem menuItem, ArrayList Targets, ProgressChangedEventHandler pce)
{
_Targets = ArrayList.ReadOnly(Targets);
_pce = pce;
_menuItem = menuItem;
try
{
_PluginThread = new Thread((new ThreadStart(StartTask)));
_PluginThread.IsBackground = _SetBackground;
_PluginThread.Start();
_Menu.Enabled = false;
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 释放当前正在运行的插件对象并回收其占用的资源(注意:该插件正在执行的任务会被立即终止)
/// </summary>
/// <returns>终止任务引发的异常</returns>
public Exception StopTask()
{
_Menu.Enabled = true;
try
{
_Current.Dispose();
// _PluginThread.Abort();
}
catch (Exception e)
{
return e;
}
return null;
}
#region 私有成员
private void TaskFinished(object sender, ProgressChangedEventArgs e)
{
if (e.Progress == e.Max)
{
_Menu.Enabled = true;
StopTask();
}
}
private bool PluginExisted(Type Type)
{
IDictionaryEnumerator GUIDenum = _Type.GetEnumerator();
while (GUIDenum.MoveNext())
{
if (GUIDenum.Current.Equals(Type.GUID))
{
MessageBox.Show("已存在插件:" + Type.Name + "\n程序集:" + Type.Assembly.FullName + "\nGUID:" + Type.GUID.ToString(), "载入插件时发生错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return true;
}
}
return false;
}
private void AddMenu(ToolStripMenuItem menu,EventHandler MenuClickHandler)
{
if (_Menu == null)
_Menu = new ContextMenuStrip();
menu.Click+=MenuClickHandler;
_Menu.Items.Add(menu);
}
private void InitializePlugins(string SearchDirectory, EventHandler MenuClickHandler)
{
string[] files = Directory.GetFiles(SearchDirectory, "*.dll");
foreach (string f in files)
{
try
{
Assembly asm = Assembly.LoadFrom(f);
Type[] types = asm.GetTypes();
foreach (Type type in types)
{
if ((type.GetCustomAttributes(typeof(PluginAttribute), false).Length > 0) && (!PluginExisted(type)) && (type.GetInterface("IPlugin") != null))
{
IPlugin iPlug = Activator.CreateInstance(type) as IPlugin;
if (iPlug != null)
{
PluginInfo pli = iPlug.PluginInfo;
pli.Menu.Tag = type.GUID.ToString();
BasePluginInfo bpi = new BasePluginInfo(pli, type.GUID);
_LoadedPlugins.Add(bpi);
AddMenu(pli.Menu, MenuClickHandler);
_Map.Add(pli.Menu, pli);
_Type.Add(pli.Menu, type);
}
}
}
}
catch (Exception e)
{
MessageBox.Show("无法加载"+f+":\n"+e.Message, "加载插件时出现错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void StartTask()
{
IDictionaryEnumerator mapEnum = _Type.GetEnumerator();
while (mapEnum.MoveNext())
{
ToolStripMenuItem t = mapEnum.Key as ToolStripMenuItem;
if (t.Tag == _menuItem.Tag)
{
Type type = mapEnum.Value as Type;
_Current = Activator.CreateInstance(type) as IPlugin;
_Current.ProgressChanged += _pce;
_Current.ProgressChanged+=new ProgressChangedEventHandler(TaskFinished);
Form f = _Current.Window;
if (f != null)
{
if (f.ShowDialog(_Parent)!=DialogResult.OK)
goto Abort;
}
_Current.AssignTask(_Targets);
Abort:
;
}
}
}
#endregion
#region IDisposable 成员
/// <summary>
/// 释放当前PluginManager所占用的资源
/// </summary>
public void Dispose()
{
_Current = null;
_Map=null;
_Type=null;
_LoadedPlugins=null;
_PluginThread=null;
_Targets=null;
_menuItem=null;
_pce=null;
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -