C# 实现动态加载DLL插件 及HRESULT:0x80131047处理
本代码实现DLL的动态加载, 类似PS里的滤镜插件!
1. 建立一个接口项目类库,此处名称为:Test.IPlugin
using System; namespace Test.IPlugin { public interface IPlugin { void Run(object obj); } }
2.建立一个DLL插件类库项目,此项目要引用接口项目'Test.IPlugin',并实现Run方法, 此处名称为:Test.Plugin
using System; namespace Test.Plugin { public class Plugin:IPlugin.IPlugin { #region IPlugin 成员 void Test.IPlugin.IPlugin.Run(object obj) { System.Windows.Forms.MessageBox.Show(obj.ToString()); } #endregion } }
3.插件动态加载实现,建立控制台或者WinForm项目及引用接口项目Test.IPlugin, 以下为动态加载代码
private void btnLoad_Click(object sender, EventArgs e) { string filePath = @"文件路径\Test.Plugin.dll"; Assembly dll = null; {//方法一:直接从DLL路径加载(网上代码,本机测试出错) //dll = Assembly.Load(filePath); } {//方法二:先把DLL加载到内存,再从内存中加载 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); byte[] bFile = br.ReadBytes((int)fs.Length); br.Close(); fs.Close(); dll = Assembly.Load(bFile); } //调用接口 foreach (var t in dll.GetTypes()) { if (t.GetInterface("IPlugin") != null) { var plugin = (IPlugin.IPlugin)Activator.CreateInstance(t); plugin.Run("test"); } } }
以上为实现动态插件模式的代码,先注意下调用插件的代码中有2种方法
----------------分割线---------------
注意第一种方法, 在Assembly.Load(filePath)时会抛出异常:
未能加载文件或程序集“***”或它的某一个依赖项。给定程序集名称或基本代码无效。 (异常来自 HRESULT:0x80131047)
在网上查了很多相关解决方案均未能解决这个错误,开发环境为VS2008,三个项目均为Framework2.0 X86模式,尝试过的方式
1.强制CPU模式为X86 2.所有DLL及EXE放置同一目录 3.取消"启用Visual Studio宿主进程"
最后无意中看到有用加载到内存的方式,然后使用BinaryReader读取字节数组再加载, 完美解决.