zoukankan      html  css  js  c++  java
  • 使用AppDomain进行动态加载和卸载dll

    加载dll最简单的写法

    Assembly.Load("<dll路径>")
    

      

    但这样写这个dll就被程序占用不可删除,即不可以卸载。

    通过AppDomain加代理的方式进行加载则可以实现卸载,从而实现程序不被占用并被删除。

    第一步,创建AssemblyProxy类

    public class AssemblyProxy : MarshalByRefObject
    {
            private Assembly assembly;
    
            public void LoadAssembly(string fullName)
            {
                assembly = Assembly.LoadFrom(fullName);
            }/// <summary>
            /// 开放委托,可使用Assembly操作
            /// </summary>
            /// <param name="action"></param>
            public T Work<T>(Func<Assembly, T> action)
            {
                return action.Invoke(assembly);
            }
    }

    AssemblyProxy类将运行在子AppDomain中,通过操作AssemblyProxy类进行反射加载的DLL。保证AppDomain.CurrentDomain和子AppDomain隔离,最后卸载子AppDomain就实现了动态加载和卸载dll的目标。

    第二步,实现AssemblyLoader类

    public class AssemblyLoader
    {
            private AppDomain appDomain;
    
            public AssemblyProxy Proxy;
    
            public AssemblyLoader()
            {
                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationName = "Child";
                setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private");
                setup.CachePath = setup.ApplicationBase;
                setup.ShadowCopyFiles = "true";
                setup.ShadowCopyDirectories = setup.ApplicationBase;
    
                appDomain = AppDomain.CreateDomain("ChildDomain", null, setup);
                string name = Assembly.GetExecutingAssembly().GetName().FullName;
    
           // 从子类AppDomain中反射创建AssemblyProxys实例 Proxy
    = (AssemblyProxy)appDomain.CreateInstanceAndUnwrap(name, typeof(AssemblyProxy).FullName); } public void LoadAssembly(string fullName) { Proxy.LoadAssembly(fullName); } public void Unload() { AppDomain.Unload(appDomain); appDomain = null; } }

    接着就可以使用了

    var loader = new AssemblyLoader();
    loader.LoadAssembly(path);
    
    var version = loader.Proxy.Work(assembly =>
    {
         return assembly.GetName().Version.ToString();
    });
    
    loader.Unload();
  • 相关阅读:
    hyper-v使用wifi链接网络
    windows下批量换程序——运维常用
    redis多端口,多实例。
    vs2017 本地IP地址调试 局域网调试
    自动备份
    ipv6无网络访问权限怎么办
    缓存
    学习php
    DateTimeOffset DateTime
    C# 集合
  • 原文地址:https://www.cnblogs.com/saving/p/10551441.html
Copyright © 2011-2022 走看看