使用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();

原文地址:https://www.cnblogs.com/saving/p/10551441.html

时间: 2024-08-07 00:13:34

使用AppDomain进行动态加载和卸载dll的相关文章

AppDomain 详解二【转】-C#中动态加载和卸载DLL

在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方 卸载.在C#中我们也能使用Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何 卸载的方法.这是由于托管代码的自动垃圾回收机制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做. 这引发了一个问题,用Assembly加载的DLL可能只在程序结束的时候才会被释放,这也意味着在程序运行

C#中动态加载和卸载DLL

在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方 卸载.在C#中我们也能使用Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何 卸载的方法.这是由于托管代码的自动垃圾回收机制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做.  这引发了一个问题,用Assembly加载的DLL可能只在程序结束的时候才会被释放,这也意味着在程序运

动态加载和卸载 DLL

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ClassLibrary1 { public class Class1 { public static void DoStuff(string msg) { Console.WriteLine("Class1.DoStuff: " + m

C#.Net 如何动态加载与卸载程序集(.dll或者.exe)

我们知道在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载. 在C#中我们也能使用Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何卸载的方法.这是由于托管代码的自动垃圾回收机 制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做. 但是我们可以通过应用程序域(AppDomain)来实现加载域卸载,如下会演示如何使用的.当Ap

最近看到有同学在问C#如何动态加载C的DLL,所以在这里跟大家分享一下!

本文以VS2013来做开发示例,请知悉!(注C#项目仅设置了Debug解决方案,release一样的更改即可). 如下图,工程分为3个: TestDLL是导出库,导出 test_hello 函数作为要被加载的测试DLL: DynamicLoadDemo 为动态加载C#动态加载DLL的方式:(注:LoadLibrary.GetProcAddress.FreeLibrary) StaticLoadDemo为为静态加载C#动态加载DLL的方式.(注:DllImport) TestDLL:源码展示 Te

HOOK - 远程加载与卸载DLL

// 获取进程ID DWORD GetProcessIdByName(LPCTSTR szProcess)//注意要加exe后缀 { DWORD dwRet=0; HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); PROCESSENTRY32 pe32; pe32.dwSize=sizeof(PROCESSENTRY32); Process32First(hSnapshot,&pe32); do { if (_tcs

通过应用程序域AppDomain加载和卸载程序集

微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要你费一些心思.我在学习Remoting的时候,就遇到一个扰人的问题,就是Remoting为远程对象仅提供Register的方法,如果你要注销时,只有另辟蹊径.细心的开发员,会发现Visual Studio.Net中的反射机制,同样面临这个问题.你可以找遍MSDN的所有文档,在Assembly类中,你永远只能看到Load方法,却无法寻觅到Unload的踪迹.难道我们装载了程序集后,就不能再将它卸载下来

Unity的动态加载简单使用

Unity的动态加载简单使用Unity可以快速,轻量化的实现IOC,不用自已写类似反射代码来动态加载类或dll了使用Unity先要用nuget获取相关引用文件Unity可通过代码或config文件来配置要加动态加载的内容 使用示例 static void Main(string[] args) { Console.WriteLine("'Y' use Config Register Type,Otherwise use Code Register Type"); bool isUseC

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

这篇文章介绍了c#动态加载卸载DLL的方法,有需要的朋友可以参考一下 c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法.在.net 中,加入了应用程序域的概念,应用程序域是可以卸载的.也就是说,如果需要对动态加载的dll程序集进行更新,可以通过以下方法解决: 新建一个应用程序域,在该应用程序域中动态加载DLL,然后可以卸载掉该应用程序域.该应用程序域被卸载的时候,相关资源也会被回收. 要想这样实现,就要让你程序的cur