惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
IT之家
IT之家
博客园 - 叶小钗
雷峰网
雷峰网
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
SegmentFault 最新的问题
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
博客园 - 【当耐特】
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
Jina AI
Jina AI
博客园 - Franky
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美

博客园 - uxinxin

.NET10 中配置Swagger的记录 .NET10中通过appsettings.json配置文件获取信息的几个方法 学习使用Taurus的微服务群在.NET Framework4.8环境下的搭建 .net framework 中Owin 通过启动类 Startup.cs 使用 SignalR B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【八】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【七】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【六】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【五】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【四】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【三】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【二】 B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 .NET程序屏蔽一些无效蜘蛛的访问配置 Framework 4.6.2下的SignalR使用,以及WPF下同步使用 react 16.8.4版本中的生命周期中的细节 在组件挂在时使用了定时器的处理——尚硅谷React教程(2022加更,B站超火react教程)学习笔记 CYQ.Data的XML操作的一些自己使用记录 IIS URL Rewrite将伪静态配置文件放在web.config外部 ASP.NET Core EF MVC 登录验证 一步步教你用html+div+css+js基于Jquery实现一套数字华容道游戏
asp.net 动态加载与卸载程序集的尝试(没有成功)欢迎解决的...
uxinxin · 2024-07-17 · via 博客园 - uxinxin

参考 C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集 - 龙骑科技 - 博客园 (cnblogs.com)

大概意思是微软的.NET运行不支持直接卸载应用程序集,因为一旦加载程序集,即使是动态加载就会给该程序集加载到当前正在运行的主线程上,如果想卸载程序集就需要停掉当前主线程,所以不能这么操作。

文章介绍为了实现动态加载和卸载,可以通过AppDomain创建子程序集,需要卸载时就卸载掉整个AppDomain,

但是不知道什么原因,在执行AppDomain加载子程序集时跟断点明明已经拿到了dll文件的程序集,但在返回的时候会报没有序列化的异常。

接下来我给我的代码运行代码贴出来看一下

首先创建Plugin1类库项目并创建One.cs文件内容如下发布出文件为Plugin1.dll文件

using System;

namespace Plugin1
{
    [Serializable]
    public class One : MarshalByRefObject
    {
        public string GetName(string name)
        {
            return "输出当前名字:" + name;
        }
    }
}

然后创建新的测试项目首先创建类ObjectLoader1.cs文件代码如下

  1 using System;
  2 using System.Collections;
  3 using System.Reflection;
  4 
  5 /// <summary>
  6 /// ObjectLoader 的摘要说明
  7 /// </summary>
  8 public class ObjectLoader1:IDisposable
  9 {
 10     protected Hashtable domains = new Hashtable();
 11     public ObjectLoader1() { }
 12     public object GetObject(string dllName,string typeName,object[] constructorParms)
 13     {
 14         AssemblyLoader al = null;
 15         object o = null;
 16         if (al == null)
 17         {
 18             AppDomainSetup setup = new AppDomainSetup();
 19             setup.ShadowCopyFiles = "true";
 20             AppDomain domain = AppDomain.CreateDomain(dllName, null, setup);
 21             domains.Add(dllName, domain);
 22             object[] parms = { dllName };
 23             BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
 24             try
 25             {
 26                 var ww = CYQ.Data.AppConst.WebRootPath;
 27                 var currAssembly=Assembly.GetExecutingAssembly();
 28                 al = (AssemblyLoader)domain.CreateInstanceFromAndUnwrap(currAssembly.CodeBase, "AssemblyLoader", true, bindings, null, parms, null, null);
 29             }
 30             catch (Exception e1)
 31             {
 32                 throw new Exception();
 33             }
 34         }
 35         if (al != null)
 36         {
 37             o = al.GetAssembly();
 38         }
 39         return o;
 40     }
 41     public void Unload(string dllName)
 42     {
 43         if (domains.ContainsKey(dllName))
 44         {
 45             AppDomain domain = (AppDomain)domains[dllName];
 46             AppDomain.Unload(domain);
 47             domains.Remove(dllName);
 48         }
 49     }
 50     ~ObjectLoader1() {
 51         dispose(false);
 52     }
 53     public void Dispose() {
 54         dispose(true);
 55     }
 56     private void dispose(bool disposing)
 57     {
 58         if (disposing)
 59         {
 60             foreach(object o in domains.Keys)
 61             {
 62                 string dllName = o.ToString();
 63                 Unload(dllName);
 64             }
 65             domains.Clear();
 66         }
 67     }
 68 }
 69 public class AssemblyLoadFailureException1 : Exception
 70 {
 71     public AssemblyLoadFailureException1() : base()
 72     {
 73     }
 74 
 75     public override string Message
 76     {
 77         get
 78         {
 79             return "Assembly Load Failure";
 80         }
 81     }
 82 
 83 }
 84 public class AssemblyLoader1 : MarshalByRefObject, IDisposable
 85 {
 86     private Assembly a = null;
 87     public AssemblyLoader1() { }
 88     public AssemblyLoader1(string fullPath) {
 89         if (a == null)
 90         {
 91             a = Assembly.LoadFrom(fullPath);
 92         }
 93     }
 94     ~AssemblyLoader1() {
 95         dispose(false);
 96     }
 97     public void Dispose()
 98     {
 99         dispose(true);
100     }
101     private void dispose(bool disposing)
102     {
103         if (disposing)
104         {
105             a = null;
106             GC.Collect();
107             GC.WaitForPendingFinalizers();
108             GC.Collect(0);
109         }
110     }
111     public Assembly GetAssembly()
112     {
113         return a;
114     }
115     public Assembly LoadAssembly(string dllName)
116     {
117         try
118         {
119             a = Assembly.LoadFrom(dllName);
120             return a;
121         }
122         catch (Exception)
123         {
124             throw new AssemblyLoadFailureException1();
125         }
126     }
127 }

然后调用代码

1 var ww = AppDomain.CurrentDomain.BaseDirectory;
2 ObjectLoader1 ol = new ObjectLoader1();
3 var o = ol.GetObject(ww + "Plugin1.dll", "Plugin1.One", new object[] { });

断点ObjectLoader1.cs文件的37行,和ObjectLoader1.cs的113行,F10执行,会发现在执行完113行之后代码正常返回,但紧跟着回到第37行时,代码抛出异常

System.IO.FileNotFoundException:“未能加载文件或程序集“Plugin1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的

接下来就不知道如何解决了,只能搁置到这里了,如果哪位大神有解决方案希望可以告知!


第二种方法,这个是通过大模型提供的方法

代码如下

AppDomainLoader.cs文件
 1 using System;
 2 using System.Reflection;
 3 
 4 /// <summary>
 5 /// AppDomainLoader 的摘要说明
 6 /// </summary>
 7 public class AppDomainLoader
 8 {
 9     public void One(string dllName)
10     {
11         // 创建新的 AppDomain
12         AppDomain domain = AppDomain.CreateDomain("MyDomain");
13 
14         var ww = CYQ.Data.AppConst.WebRootPath;
15         // 要加载的程序集的文件路径
16         string dllPath = ww + "Plugin1.dll";
17         dllPath = dllName;
18         try
19         {
20             var str= AssemblyName.GetAssemblyName(dllPath);
21 
22             //object[] parms = { dllPath };
23             //BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
24             //var al = domain.CreateInstanceFromAndUnwrap(str.CodeBase, "Plugin1.One", true, bindings, null, parms, null, null);
25             // 加载程序集到 AppDomain
26             Assembly assembly = domain.Load(str);
27 
28             // 获取类型
29             Type type = assembly.GetType("Plugin1.One");
30 
31             // 实例化对象
32             if (type != null)
33             {
34                 object instance = Activator.CreateInstance(type);
35 
36                 // 在这里可以调用对象的方法或访问其属性
37                 // 例如:
38                 MethodInfo method = type.GetMethod("GetName");
39                 if (method != null)
40                 {
41                     method.Invoke(instance, new[] { "这是名字"});
42                 }
43                 else
44                 {
45                     throw new Exception();
46                 }
47             }
48             else
49             {
50                 throw new Exception();
51             }
52         }
53         catch (Exception ex)
54         {
55             throw new Exception();
56         }
57         finally
58         {
59             // 卸载 AppDomain 以释放程序集和资源
60             AppDomain.Unload(domain);
61         }
62 
63     }
64 }

外部调用方法如下

1       var ww = AppDomain.CurrentDomain.BaseDirectory;
2             var adl = new AppDomainLoader();
3             adl.One(ww + "Plugin1.dll");

这个同样在执行加载程序集时报错,

AppDomainLoader.cs文件的22,23,24行注释可以打开运行测试,也报错,因为知识有限,不知道如何解决