2010-05-01 来自:csharpwin.com 字体大小:【
大 中 小】
首先,为了动态的在内存中装载程序或程序集,我们以文件流的方式读取二进制文件,并将其以字节的形式保存在数组中,代码如下:
//动态加载插件
String pluginFilePath = Path.GetDirectoryName(Application.ExecutablePath) +
"\\plugins\\PluginLibrary.dll";
FileStream fs = new FileStream(pluginFilePath, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
fs.Close();
br.Close();
然后,利用 Assembly 类的 Load 重载方法,以数组的形式加载该程序集。代码如下:
Assembly assembly = Assembly.Load(bin);
public class PlugingManager
{
//插件装载器
public ArrayList Plugins = new ArrayList();
//插件FullName
public ArrayList PlugFullName = new ArrayList();
//插件类型
public ArrayList PlugTypes = new ArrayList();
#region 构造函数
/// <summary>
/// PlugingManager插件加载
/// </summary>
/// <param name="plugspath">插件所在目录必须是运行目录中的文件夹</param>
/// <param name="StartsWith">加载指定插件(插件包含的名称)</param>
/// <param name="InterfaceName">插件接口名称</param>
public PlugingManager(string plugspath,string StartsWith,string InterfaceName)
{
//获取插件目录(plugins)下所有文件
string[] files = Directory.GetFiles(Application.StartupPath + @"\\" + plugspath);
foreach (string file in files)
{
if (file.ToUpper().EndsWith(StartsWith.ToUpper()))
{
try
{
//Assembly ab = Assembly.LoadFrom(file);
Assembly ab = null;
//先将插件拷贝到内存缓冲
byte[] addinStream = null;
using(FileStream input = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
BinaryReader reader = new BinaryReader(input);
addinStream = reader.ReadBytes((int) input.Length);
}
ab = Assembly.Load(addinStream); //加载内存中的Dll
Type[] types = ab.GetTypes();
foreach (Type t in types)
{
if (t.GetInterface(InterfaceName) != null)
{
Plugins.Add(ab.CreateInstance(t.FullName));
PlugFullName.Add(t.FullName);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
#endregion
}
PlugingManager plug =
new PlugingManager(
"Plugs",
"Garden.Plugs.dll",
"IPlug");
var win = plug.Plugins.ToArray().FirstOrDefault(m => ((Type)m.GetType()).Name.ToLower() ==
this.Tag.ToString().ToLower());
MethodInfo OnShowDlg = ((Type)win.GetType()).GetMethod(
"ShowSelf");
Form cl = (Form)OnShowDlg.Invoke(win,
null);
cl.WindowState = FormWindowState.Maximized;
cl.MdiParent =
this;
cl.Show();
foreach (
object obj
in plug.Plugins)
{
Type t = obj.GetType();
MethodInfo OnShowDlg = t.GetMethod(
"ShowSelf");
Control cl = (Control)OnShowDlg.Invoke(obj,
null);
Control con = GetControlFromForm(t.Name,
this);
if (con !=
null)
{
con.Controls.Add(cl);
cl.Dock = DockStyle.Fill;
isbreak =
false;
con =
null;
}
}