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

  • 相关阅读:
    Vue 多层组件传值(最外层组件>中间组件>最内部组件)
    Vue 父子组件传值 (Vue-cli4)
    CSS HTML 基本知识 盒子模型 Flex等
    Vue---基本知识
    springboot ---邮件和定时任务 和异步
    js中.bind()和.call()用法讲解
    为页内的tab添加的iframe添加加载动画过渡效果
    JMETER学习宝典
    新篇章,新起点
    计划拟定(现阶段)
  • 原文地址:https://www.cnblogs.com/hanf/p/4079236.html
Copyright © 2020-2023  润新知