前一段看了看Sharepdevlop的源代码。里边的插件树给了我写程序的启发。于是就想写一个自己的插件管理。
下边是我的程序贴图
主要做的是功能的动态加载。可以单独开发每个功能。只要将其类写在配置文件中即可。配置文件如下:
name是对应的菜单内部名子。path对应的是要插入到那个菜单的下边,如果是空则为最上级菜单。text是程序中显示的名子,classname是该功能菜单所对应的类。
然后定义一个通一的结口。用以实现在主程序中的调用
下边代码是加载插件。
下边是我的程序贴图
主要做的是功能的动态加载。可以单独开发每个功能。只要将其类写在配置文件中即可。配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<class dll ="AddIn\EditAddin\EditMenu.dll">
<menuitem name ="editmenuitem" path ="" text="编辑" classname ="EditMenu.EditMenu" />
<menuitem name ="selectallmenuitem" path ="editmenuitem" text="全选" classname ="EditMenu.SelectAll" />
<menuitem name ="copymenuitem" path ="editmenuitem" text="复制" classname ="EditMenu.Copy" />
<menuitem name ="cutmenuitem" path ="editmenuitem" text="剪切" classname ="EditMenu.Cut" />
<menuitem name ="pastemenuitem" path ="editmenuitem" text="粘贴" classname ="EditMenu.Paste" />
</class>
这是编辑菜单的配置文件<class dll ="AddIn\EditAddin\EditMenu.dll">
<menuitem name ="editmenuitem" path ="" text="编辑" classname ="EditMenu.EditMenu" />
<menuitem name ="selectallmenuitem" path ="editmenuitem" text="全选" classname ="EditMenu.SelectAll" />
<menuitem name ="copymenuitem" path ="editmenuitem" text="复制" classname ="EditMenu.Copy" />
<menuitem name ="cutmenuitem" path ="editmenuitem" text="剪切" classname ="EditMenu.Cut" />
<menuitem name ="pastemenuitem" path ="editmenuitem" text="粘贴" classname ="EditMenu.Paste" />
</class>
name是对应的菜单内部名子。path对应的是要插入到那个菜单的下边,如果是空则为最上级菜单。text是程序中显示的名子,classname是该功能菜单所对应的类。
然后定义一个通一的结口。用以实现在主程序中的调用
using System;
using System.Collections.Generic;
using System.Text;
namespace MainCommand
{
public interface ICommand
{
void Run();
}
public interface IMenuCommand:ICommand
{
void CheckItem(object sender, EventArgs e);
}
public interface IMenuCheckCommand : IMenuCommand
{
bool Check
{
get;
set;
}
bool Endable
{
get;
set;
}
}
}
using System.Collections.Generic;
using System.Text;
namespace MainCommand
{
public interface ICommand
{
void Run();
}
public interface IMenuCommand:ICommand
{
void CheckItem(object sender, EventArgs e);
}
public interface IMenuCheckCommand : IMenuCommand
{
bool Check
{
get;
set;
}
bool Endable
{
get;
set;
}
}
}
下边代码是加载插件。
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using MainCommand;
namespace MenuManage
{
//和配置文件中的属性对应
public class AddInXmlMenuItem
{
/// <summary>
///
/// </summary>
public string menuname;
public string menutext;
public string menupath;
public string classname;
}
public class AddInXmlmenu
{
/// <summary>
/// 用来载入动态库
/// </summary>
Assembly loadedAssembly = null;
/// <summary>
/// 存存配置信息
/// </summary>
public List<AddInXmlMenuItem> AddInXmlList = new List<AddInXmlMenuItem>();
public List<IMenuCommand> MenuCommandList = new List<IMenuCommand>();
/// <summary>
/// 动态库的路径
/// </summary>
public string classdll;
/// <summary>
/// 装载配置文件
/// </summary>
/// <param name="xmlname"></param>
public void LoadAddInXml(string xmlname)
{
XmlDocument document = new XmlDocument();
document.XmlResolver = null;
document.Load(xmlname);
for (int i = 0; i < document.ChildNodes.Count; i++)
{
XmlNode firstnode = document.ChildNodes[i];
if (firstnode.Name.Equals("class"))
{
classdll = firstnode.Attributes["dll"].Value;
loadedAssembly = Assembly.LoadFrom(classdll);
for (int j = 0; j < firstnode.ChildNodes.Count; j++)
{
XmlNode menunode = firstnode.ChildNodes[j];
switch (menunode.Name)
{
case "menuitem":
{
AddInXmlMenuItem item = new AddInXmlMenuItem();
item.classname = menunode.Attributes["classname"].Value;
item.menuname = menunode.Attributes["name"].Value;
item.menupath = menunode.Attributes["path"].Value;
item.menutext = menunode.Attributes["text"].Value;
IMenuCommand command = loadedAssembly.CreateInstance(item.classname) as IMenuCommand;
AddInXmlList.Add(item);
MenuCommandList.Add(command);
}
break;
default:
break;
}
}
}
}
}
}
static class AddInClass
{
public static MenuStrip MenuObject;
static public List<AddInXmlmenu> AddInXml = new List<AddInXmlmenu>();
/// <summary>
/// 初始化插件
/// </summary>
static public void InitAddInClass()
{
//读取插件
string[] straddin = Directory.GetDirectories("AddIn");
for (int i = 0; i < straddin.Length; i++)
{
string pathstr = straddin[i];
string[] filename = Directory.GetFiles(pathstr);
for (int j = 0; j < filename.Length; j++)
{
string exte = Path.GetExtension(filename[j]);
if (exte.Equals(".AddIn"))
{
AddInXmlmenu tempxmlmenu = new AddInXmlmenu();
tempxmlmenu.LoadAddInXml(filename[j]);
if (tempxmlmenu.AddInXmlList.Count > 0)
{
AddInXml.Add(tempxmlmenu);
}
}
}
}
}
/// <summary>
/// 增加菜单
/// </summary>
static public void AddMenuItem()
{
for (int i = 0; i < AddInXml.Count; i++)
{
AddInXmlmenu itemmenu = AddInXml[i];
for (int j = 0; j < itemmenu.AddInXmlList.Count; j++)
{
AddInXmlMenuItem item = itemmenu.AddInXmlList[j];
ToolStripMenuItem toolitem = CreateMenuItem(item.menuname, item.menutext, item.menupath);
if (toolitem == null)
{
continue;
}
IMenuCommand command = itemmenu.MenuCommandList[j] as IMenuCommand;
command.Run();
toolitem.Click +=new EventHandler(command.CheckItem);
}
}
}
/// <summary>
/// 建立菜单项目
/// </summary>
/// <param name="name"></param>
/// <param name="text"></param>
/// <param name="menu"></param>
static private ToolStripMenuItem CreateMenuItem(string name, string text, string menu)
{
if (MenuObject != null)
{
ToolStripMenuItem item = new ToolStripMenuItem();
item.Name = name;
item.Text = text;
if (menu == "")
{
MenuObject.Items.Add(item);
}
else
{
ToolStripMenuItem parent = GetToolItem(menu);
if (parent != null)
{
parent.DropDownItems.Add(item);
}
}
return item;
}
return null;
}
/// <summary>
/// 得到要插入的菜单项
/// </summary>
/// <param name="itempath"></param>
/// <returns></returns>
static private ToolStripMenuItem GetToolItem(string itempath)
{
string[] word = itempath.Split('\\');
ToolStripMenuItem item = MenuObject.Items[word[0]] as ToolStripMenuItem;
if (item != null)
{
for (int i = 1; i < word.Length; i++)
{
if (word[i].Length > 0)
{
item = item.DropDownItems[word[i]] as ToolStripMenuItem;
}
}
}
else
{
return null;
}
return item;
}
}
}
以下是源代码地址:https://files.cnblogs.com/xtpgkxk/插件管理.rar
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using MainCommand;
namespace MenuManage
{
//和配置文件中的属性对应
public class AddInXmlMenuItem
{
/// <summary>
///
/// </summary>
public string menuname;
public string menutext;
public string menupath;
public string classname;
}
public class AddInXmlmenu
{
/// <summary>
/// 用来载入动态库
/// </summary>
Assembly loadedAssembly = null;
/// <summary>
/// 存存配置信息
/// </summary>
public List<AddInXmlMenuItem> AddInXmlList = new List<AddInXmlMenuItem>();
public List<IMenuCommand> MenuCommandList = new List<IMenuCommand>();
/// <summary>
/// 动态库的路径
/// </summary>
public string classdll;
/// <summary>
/// 装载配置文件
/// </summary>
/// <param name="xmlname"></param>
public void LoadAddInXml(string xmlname)
{
XmlDocument document = new XmlDocument();
document.XmlResolver = null;
document.Load(xmlname);
for (int i = 0; i < document.ChildNodes.Count; i++)
{
XmlNode firstnode = document.ChildNodes[i];
if (firstnode.Name.Equals("class"))
{
classdll = firstnode.Attributes["dll"].Value;
loadedAssembly = Assembly.LoadFrom(classdll);
for (int j = 0; j < firstnode.ChildNodes.Count; j++)
{
XmlNode menunode = firstnode.ChildNodes[j];
switch (menunode.Name)
{
case "menuitem":
{
AddInXmlMenuItem item = new AddInXmlMenuItem();
item.classname = menunode.Attributes["classname"].Value;
item.menuname = menunode.Attributes["name"].Value;
item.menupath = menunode.Attributes["path"].Value;
item.menutext = menunode.Attributes["text"].Value;
IMenuCommand command = loadedAssembly.CreateInstance(item.classname) as IMenuCommand;
AddInXmlList.Add(item);
MenuCommandList.Add(command);
}
break;
default:
break;
}
}
}
}
}
}
static class AddInClass
{
public static MenuStrip MenuObject;
static public List<AddInXmlmenu> AddInXml = new List<AddInXmlmenu>();
/// <summary>
/// 初始化插件
/// </summary>
static public void InitAddInClass()
{
//读取插件
string[] straddin = Directory.GetDirectories("AddIn");
for (int i = 0; i < straddin.Length; i++)
{
string pathstr = straddin[i];
string[] filename = Directory.GetFiles(pathstr);
for (int j = 0; j < filename.Length; j++)
{
string exte = Path.GetExtension(filename[j]);
if (exte.Equals(".AddIn"))
{
AddInXmlmenu tempxmlmenu = new AddInXmlmenu();
tempxmlmenu.LoadAddInXml(filename[j]);
if (tempxmlmenu.AddInXmlList.Count > 0)
{
AddInXml.Add(tempxmlmenu);
}
}
}
}
}
/// <summary>
/// 增加菜单
/// </summary>
static public void AddMenuItem()
{
for (int i = 0; i < AddInXml.Count; i++)
{
AddInXmlmenu itemmenu = AddInXml[i];
for (int j = 0; j < itemmenu.AddInXmlList.Count; j++)
{
AddInXmlMenuItem item = itemmenu.AddInXmlList[j];
ToolStripMenuItem toolitem = CreateMenuItem(item.menuname, item.menutext, item.menupath);
if (toolitem == null)
{
continue;
}
IMenuCommand command = itemmenu.MenuCommandList[j] as IMenuCommand;
command.Run();
toolitem.Click +=new EventHandler(command.CheckItem);
}
}
}
/// <summary>
/// 建立菜单项目
/// </summary>
/// <param name="name"></param>
/// <param name="text"></param>
/// <param name="menu"></param>
static private ToolStripMenuItem CreateMenuItem(string name, string text, string menu)
{
if (MenuObject != null)
{
ToolStripMenuItem item = new ToolStripMenuItem();
item.Name = name;
item.Text = text;
if (menu == "")
{
MenuObject.Items.Add(item);
}
else
{
ToolStripMenuItem parent = GetToolItem(menu);
if (parent != null)
{
parent.DropDownItems.Add(item);
}
}
return item;
}
return null;
}
/// <summary>
/// 得到要插入的菜单项
/// </summary>
/// <param name="itempath"></param>
/// <returns></returns>
static private ToolStripMenuItem GetToolItem(string itempath)
{
string[] word = itempath.Split('\\');
ToolStripMenuItem item = MenuObject.Items[word[0]] as ToolStripMenuItem;
if (item != null)
{
for (int i = 1; i < word.Length; i++)
{
if (word[i].Length > 0)
{
item = item.DropDownItems[word[i]] as ToolStripMenuItem;
}
}
}
else
{
return null;
}
return item;
}
}
}