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读取字节数组再加载, 完美解决.

 

posted @ 2014-11-06 16:31  Hanf  阅读(10935)  评论(5编辑  收藏  举报
Copyright © 2008-2016 Hanf All Rights Reserved