⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pluginmanager.cs

📁 自己写的可扩展插件文件管理器
💻 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 + -