前段时间工作的时候遇到一个问题。就是需要每次启动程序的时候动态替换掉某个dll,所以就百度了这方面的资料。这次记录下来让自己以后可以看。

  根据自己的理解,动态卸载dll需要有以下条件:

    1:dll在加载在Appdomin(应用程序域)中,从而通过卸载Appdomin来动态卸载dll。

  

  以下代码从网上抄过来的,加上了一些注释。

--------------------------------------------------------------------------------------------------------主程序代码-------------------------------------------------------------------------------------------------------

namespace UnloadDllDemo
{
  class Program
  {
    static void Main(string[] args)
    {
    string callingDomainName = AppDomain.CurrentDomain.FriendlyName;//Thread.GetDomain().FriendlyName;
    Console.WriteLine(callingDomainName);
    AppDomain ad = AppDomain.CreateDomain("DLL Unload test");   //创建应用程序域

      //创建应用程序域的代理实例,其中代码必须继承 MarshalByRefObject,两个参数分别为代理类所在的程序集名称和完整类名
    ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap("UnloadDllDemo.exe", "UnloadDllDemo.ProxyObject"); 

    //动态加载dll
    obj.LoadAssembly();

    //调用代理类中的方法,三个参数分别为加载的dll中的完整类名,方法名,方法参数。
    obj.Invoke("MyDll.Class1", "Test", "It's a test");

    //卸载应用程序域实现dll的动态卸载
    AppDomain.Unload(ad);
    obj = null;
    Console.ReadLine();
    }
  }
  public class ProxyObject : MarshalByRefObject
  {
    Assembly assembly = null;
    public void LoadAssembly()
    {

      //动态加载dll
      assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory+@"MyDll.dll");
    }
    public bool Invoke(string fullClassName, string methodName, params Object[] args)
    {
      if (assembly == null)
      return false;
      Type tp = assembly.GetType(fullClassName);
      if (tp == null)
      return false;
      MethodInfo method = tp.GetMethod(methodName);
      if (method == null)
      return false;
      Object obj = Activator.CreateInstance(tp);
      method.Invoke(obj, args);
      return true;
    }
  }

} 

--------------------------------------------------------------------------------------------------------MyDll.dll代码------------------------------------------------------------------------------------------------------

namespace MyDll
{
  public class Class1
  {
    public Class1()
    { }

    public void Test(string Str)
    {
      Console.WriteLine(Str);
    }
  }
}

注意:

1. 要想让一个对象能够穿过AppDomain边界,必须要继承MarshalByRefObject类,否则无法被其他AppDomain使用。(我的理解是必须让代理类继承MarshalByRefObject才能让dll在AppDomain加载,否则dll只能在主程序中加载)。

2. 每个线程都有一个默认的AppDomain,可以通过Thread.GetDomain()来得到

 

c#动态加载卸载DLL的更多相关文章

  1. c#动态加载卸载DLL的方法

    这篇文章介绍了c#动态加载卸载DLL的方法,有需要的朋友可以参考一下 c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法.在 ...

  2. 2018-2-13-C#-动态加载卸载-DLL

    title author date CreateTime categories C# 动态加载卸载 DLL lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:2 ...

  3. C# 动态加载卸载 DLL

    我最近做的软件,需要检测dll或exe是否混淆,需要反射获得类名,这时发现,C#可以加载DLL,但不能卸载DLL.于是在网上找到一个方法,可以动态加载DLL,不使用时可以卸载. 我在写一个WPF 程序 ...

  4. C# 动态加载程序集dll (实现接口)

    一.程序集(接口程序集):LyhInterface.Dll namespace LyhInterface { public interface ILyhInterface { void Run(); ...

  5. C#动态加载/卸载Assembly的解决方案

    1.  Assembly中的类要从MarshalByRefObject继承,如果你想从你自己的类来继承,那么请选用interface或者继续研究其他解决方案. namespace Library { ...

  6. C# VS 调试 动态加载的 DLL

    原文:https://www.cnblogs.com/DasonKwok/p/10510218.html 在这篇文章的底部,有提供示例的Demo,可以参考一下哦,拿来直接就可以运行. 说明: 编译类库 ...

  7. CE驱动动态加载卸载

    加载: #define DEV_KEY TEXT("Drivers\\Builtin\\WCDMA") BOOL CGPRSCTRLDlg::Load() { //DWORD dw ...

  8. C#实现反射调用动态加载的DLL文件中的方法

    反射的作用:1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型 2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射.3. ...

  9. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

    实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...

随机推荐

  1. mysql 服务启动失败

    mysql 数据库连接失败 1.用naviCat Preiumn 连接本地的mysql 失败,查找原因,mysql 数据库服务没有启用,但是在服务列表里面没有找到对应的mysql 服务. 所以在cmd ...

  2. VLOOKUP和MATCH嵌套以高效引用多列数据

    VLOOKUP函数在日常工作中十分常见,以至于你要是没用过VLOOKUP函数,你都不好意思说你懂EXCEL. 一般情况下,我们需要在源数据中查找某个指定列的数据,就会用到VLOOKUP函数(如果是指定 ...

  3. Python快速入门之与C语言异同

    代码较长,建议使用电脑阅读本文. 10分钟入门Python 本文中使用的是Python3如果你曾经学过C语言,阅读此文,相信你能迅速发现这两种语言的异同,达到快速入门的目的.下面将开始介绍它们的异同. ...

  4. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  5. leetCode:206 反转链表

    206. 反转链表 题目:反转一个单链表. 进阶:链表可以迭代或递归地反转.你能否两个都实现一遍? 非递归代码: class Solution { public ListNode reverseLis ...

  6. Lombok介绍、使用方法和总结

    1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by adding 'handlers' that know how ...

  7. 在RE了16次之后,没想到还可以这样Runtime error

    这是POJ: RE的原因: 比如: int b=2147483647; for(int i=0;i<=b;++i){ .... } 应该懂了吧, 2147483647是int能表示的最大整数 解 ...

  8. Linux快速搭建FTP服务器

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(A ...

  9. Android学习笔记2——shape

    Android有很多特别的xml文件,如常用的selector.style以及shape,熟练使用这些xml可以是我们的项目变得更个性化. 一.子标签(corners.gradient.padding ...

  10. Notepad++中实现Markdown语法高亮与实时预览

    Notepad ++是一个十分强大的编辑器,除了可以用来制作一般的纯文字说明文件,也十分适合编写计算机程序代码.Notepad ++不仅有语法高亮度显示,也有语法折叠功能,并且支持宏以及扩充基本功能的 ...