首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何以递归方式将所有引用加载到AppDomain的程序集?

要以递归方式将所有引用加载到AppDomain的程序集,可以使用以下方法:

  1. 使用AppDomain.CurrentDomain.GetAssemblies()方法获取当前AppDomain中所有已加载的程序集。
  2. 遍历每个程序集,获取其引用的其他程序集。
  3. 对于每个引用程序集,检查它是否已经加载到AppDomain中。如果没有,则使用Assembly.Load()方法将其加载到AppDomain中。
  4. 递归执行步骤2和3,直到所有引用程序集都已加载。

以下是一个示例代码:

代码语言:csharp
复制
public static void LoadAllReferencedAssemblies()
{
    var loadedAssemblies = new HashSet<string>(AppDomain.CurrentDomain.GetAssemblies().Select(a => a.FullName));
    var loadedAssemblyPaths = new HashSet<string>(AppDomain.CurrentDomain.GetAssemblies().Select(a => a.Location));

    var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");
    foreach (var path in referencedPaths)
    {
        var assemblyName = AssemblyName.GetAssemblyName(path);
        if (!loadedAssemblies.Contains(assemblyName.FullName))
        {
            var assembly = Assembly.LoadFrom(path);
            var referencedAssemblies = assembly.GetReferencedAssemblies();
            foreach (var referencedAssembly in referencedAssemblies)
            {
                if (!loadedAssemblies.Contains(referencedAssembly.FullName))
                {
                    var referencedAssemblyPath = Path.Combine(Path.GetDirectoryName(path), referencedAssembly.Name + ".dll");
                    if (File.Exists(referencedAssemblyPath))
                    {
                        LoadAllReferencedAssemblies(referencedAssemblyPath);
                    }
                }
            }
        }
    }
}

这个方法可以确保所有引用程序集都被加载到AppDomain中,从而可以确保所有类型都可以被正确地加载和使用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

关于CLR内存管理一些深层次的讨论

从与程序集的关系来讲,我们可以将应用程序域看成是加载程序集的容器。只有相关的程序集被CLR加载到相应的应用程序域中,才谈得上代码的执行。 基于应用程序域的隔离,归根结底是内存的隔离。...所谓“中立域 ”方式加载的程序集,就是说程序集并不被加载到当前的程序域中并被该程序域专用,而是加载到一个公共的程序域中被所有程序域共享。...从某种意义上讲,在字符串驻留机制下,字符串也是以“中立域”的方式被加载的,被驻留的字符串能够被同一个进程下所有应用程序域所共享。 那么,我们是否可以通过一些比较直观的方式来验证这一点。...在默认的情况下,程序集被加载到当前的程序域中,供该程序集独占使用。我个人将这两种不同的程序集加载方式称为:独占加载(Exclusive Loading )和共享加载(Shared Loading)。...如右图所示:如果某个类型被定义在程序集中Foo.Dll,当AppDomain1和AppDomain2需要使用该类型的时候,它们会分别以独占的方式加载程序集Foo.Dll。

68190
  • 什么叫应用程序域?(zhuan)

    二:应用程序域和程序集 应用程序域和程序集之间的关系。在可以执行程序集中所包含的代码之前,必须将程序集加载到应用程序域中。...运行普通的应用程序会导致将几个程序集加载到一个应用程序域中。...程序集的加载方式决定其实时 (JIT) 编译代码是否可以在进程中由多个应用程序域共享,以及该程序集是否可以 从进程中卸载: 1:如果程序集是以非特定于域的形式进行加载,则共享相同安全授权集的所有应用程序域都可以共享相同的...但是,通过卸载程序集加载的所有应用程序域,可以从进程中卸载程序集。...使用此方法以避免将包含创 建的类型的程序集加载到调用程序集. 4:Unload:执行域的正常关闭.只有应用程序域中正在运行的所有线程都已停止或域中不再有运行的线程之后,才卸载 该应用程序域。

    38710

    Donut - 将 .NET 程序集作为 Shellcode 注入

    在通过 CLR 加载程序集后,原始引用将从内存中删除以阻止内存扫描器。程序集被加载到一个新的应用程序域中,以允许在一次性 AppDomains 中运行程序集。...它可用于提高 .NET 应用程序的性能、创建沙箱或只是做一些奇怪的事情。我们做后者。 它可以做的一件事是手动将 .NET 程序集加载到任意应用程序域中。它可以从磁盘或内存中执行此操作。...无论哪种方式,它都会加载到新的 AppDomain 中。在程序集加载之后但在它运行之前,解密的副本将被释放,然后使用 VirtualFree 从内存中释放以阻止内存扫描器。...最后, 如果 CLR 已经加载到宿主进程中,那么 donut 的 shellcode 仍然可以工作。.NET 程序集将被加载到托管进程内的新应用程序域中。....一次性应用程序域 当 donut 加载一个程序集时,它会将它加载到一个新的 AppDomain 中。

    2.1K00

    .NET 的程序集加载上下文

    将程序集加载到默认加载上下文中时,会自动加载其依赖项。 使用默认加载上下文时,加载到其他上下文中的依赖项将不可用,并且不能将位于探测路径外部位置的程序集加载到默认加载上下文中。...无上下文 使用反射发出生成的瞬态程序集只能选择在没有下文的情况下进行加载。在没有上下文的情况下进行加载是将具有同一标识的多个程序集加载到一个应用程序域中的唯一方式。这将省去探测成本。...在没有上下文的情况下加载具有同一标识的多个程序集会导致出现类型标识问题,这些问题与将具有同一标识的多个程序集加载到多个上下文中所导致的问题类似。 请参阅避免将一个程序集加载到多个上下文中。...位于任意路径下的插件程序集可以访问到位于探测路径中所有程序集的所有 API,但反过来探测路径下的程序集不能访问到其他目录下插件程序集的特定类型或接口等。...因为你随时可以指定应用程序的探测路径,所以它可能让你的程序以各种不确定的方式加载程序集,于是你的程序将变得很不稳定;可能完全崩溃到你无法预知的程度。

    36730

    C# Assembly

    System.AppDomain 提供了 Load方法。和Assembly 的静态Load 方法不同,AppDomaim的Load是实例方法,它允许将程序集加载到指定的AppDomain 中。...但AppDomain 的 Load 方法会返回对程序集的引用。...用法:通常用于在运行时加载程序集,适用于大多数动态加载需求。 返回值:返回一个Assembly对象,表示已加载的程序集的引用。 限制:无法跨应用程序域加载程序集,仅限于当前AppDomain。...健壮性和安全性是CLR最优先考虑的目标,如果允许应用程序以这样的一种方式崩溃,就和它的设计初衷背道而驰了。卸载程序集必须卸载包含它的整个AppDomain。...但CLR 一样不允许卸载用这两个方法加载的程序集。因为用这两个方法加载了程序集之后,仍然可以利用反射来创建对象,以便引用这些程序集中定义的元数据。如果卸载程序集,就必须通过某种方式使这些对象失效。

    8010

    多线程中的锁系统(一)-基础用法

    为了使程序在所有情况下都能够确定,是否有必要释放锁。例: Monitor.Enter拿不到锁 Monitor.Enter 是可以锁值类型的。锁时会装箱成新对象,所以无法做到线程同步。...程序域可以有多个,例子中我们使用AppDomain.CreateDomain方法创建的。 B:  按正常来说,每个程序域的代码都是隔离,互不影响的。...聪明的CLR会把一些基本类型Object, ValueType, Array, Enum, String, and Delegate等所在的程序集MSCorLib.dll,在CLR启动过程中都会加载到共享域...锁int实例是跨程序域的,MSCorLib中的基础类型都是这样, 极容易造成死锁。  而自定义类型则会加载到自己的程序域,不会影响其他。 字符串的锁 我们都知道锁的目的,是为了多线程下值被破坏。...如果成功找到,则直接把对应的引用返回,否则就在SystemDomain对应的managed heap中创建该 string,并加入到hash table中,并把引用返回。

    62050

    Asp.net管道模型(管线模型)之一发不可收拾

    从运行程序时的过程是这样的:系统首先分配一段内存地址空间然后把控制权交给了CLR生成默认AppDomain,然后将程序集加载到默认AppDomain中,程序正式运行(系统在托管堆中没有AppDomain...默认AppDomain随CLR而生而亡,无法以编码方式删除或者卸载其中的程序集。 下面以图的形式描述进程、线程、AppDomain的位置关系。 ?...AppDomain创建AppDomain并将该虚拟目录的程序集加载到AppDomain中(虚拟目录中可能不止一个程序集,而默认AppDomain会将整个虚拟目录下的所有程序集加载到AppDomain上)...,如果该虚拟目录的AppDomain已存在就直接使用该AppDomain,如果虚拟目录的程序集发生变化(包括web.config变化),就会新建一个AppDomain再将以变化的程序集加载到新的AppDomain...程序集中的变量和状态均保存在所属的AppDomain的内存中,如HttpContext.Current.Items、Application等(Application对象其实就是一张HashTable,可以被多个线程

    2.4K90

    AppDomain

    理解它们之间的关系对于开发高效、安全和可靠的应用程序至关重要。在本篇博客中,我们将深入探讨AppDomain和CLR的定义、它们的功能以及它们之间的关系。 什么是CLR?...加载程序集:在新创建的AppDomain中使用AppDomain.Load方法加载需要的程序集。 执行代码:在加载的程序集上执行代码。...资源清理:在卸载前手动清理可能的未管理资源,确保资源不泄漏。 2.1.3插件系统 在插件系统中,每个插件可以加载到独立的AppDomain中。...这个类允许对象通过引用进行跨 AppDomain 的调用,而不是通过值(即对象的副本)。 序列化: 如果对象不需要保持对原始实例的引用,可以通过序列化将对象的副本传递到另一个 AppDomain。...宿主不仅可以创建和配置 AppDomain,还可以在需要时卸载它们,并且可以通过适当的方式拿回线程的控制权。

    5800

    .NET基础:应用程序域AppDomain

    当然这种方式也同样适用于 ASP.NET ,这里最核心的就是需要理解:应用程序域AppDomain 不过当前随笔是以 WPF为例子的,并且原理是一样的、代码逻辑也是一样的。...Assembly不能单独执行,它必须被加载到AppDomain中,然后由AppDomain创建程序集中的类型 及 对象。...每个AppDomain引用到某个类型的时候需要把相应的assembly在各自的AppDomain中初始化。因此,每个AppDomain会单独保持一个类的静态变量。...同一应用程序域中的对象直接通信、不同应用程序域中的对象的通信方式有两种:一种是跨应用程序域边界传输对象副本(通过序列化对对象进行隐式值封送完成),一种是使用代理交换消息。...所以就需要打开 影像复制程序集 功能,这样在卸载AppDomain后,把需要升级的应用程序集进行升级替换,然后再创建新的AppDomain即可了。

    1.2K60

    C#将引用的dll嵌入到exe文件中

    当发布的程序有引用其它dll, 又只想发布一个exe时就需要把dll打包到exe 当然有多种方法可以打包, 比如微软的ILMerge,混淆器附带的打包......用代码打包的实现方式也有很好,本文只是其中一种实现方式,不需要释放文件!...,如winform_load) 这里需要注意,“引用”下的dll,需要设置“复制本地”为False,这样在bin目录下生成exe的时候就不会顺便复制dll了(这步可要可不要) using System;.../// [STAThread] static void Main() { AppDomain.CurrentDomain.AssemblyResolve..., 并实现程序集加载失败事件(当在程序目录和系统目录下找不到程序集触发), 当找不到程序集时就从资源文件加载, 先转换为字节数组再转换到程序集返回给程序, 这样dll就被加载到程序中了.

    4K20

    .Net Remoting(应用程序域) - Part.1

    本文将简单介绍Remoting的一些基本概念,包括 应用程序域、Remoting构架、传值封送(Marshal by value)、传引用封送(Marshal by reference)、远程方法回调(...应用程序域的基本操作 在.Net 中,将应用程序域封装为了AppDomain类,这个类提供了应用程序域的各种操作,包含 加载程序集、创建对象、创建应用程序域 等。...= AppDomain.CurrentDomain; AppDomain currentDomain = Thread.GetDomain(); 一个线程可以访问进程中所包含的所有应用程序域,因为虽然应用程序域是彼此隔离的...); } } } 接下来,我们再创建一个控制台应用程序,将项目命名为ConsoleApp,引用上面创建的类库项目ClassLib,然后添加如下代码: class Program...传值封送、传引用封送 在上面的例子中,当位于ConsoleApp.exe的obj引用NewDomain中创建的对象时,.Net将NewDomain中对象的状态进行复制、序列化,然后在ConsoleApp.exe

    67520

    字符串留用与字符串池

    .将副本添加到内部哈希表中,返回对该副本的引用.如果应用程序不再保持对原始String对象的引用,这时垃圾回收器就会介入,将字符串的内存强行释放掉....4、CLR默认留用程序集元数据中的字面值字符串 程序集加载时,CLR默认留用程序集元数据中的描述的所有字面值字符串,大微软知道这个过程可能因为额外的哈希表查找而显著影响性能,所以现在可以禁用此功能.通过对程序集用....为了提升性能,C#编译器在编译程序集是总是指定上述连个特性和标志. 5、CLR的4.5班版本及以上选择忽略4中的特性和标志,及显示留用指定字符串 由于CLR4.5及以上选择忽略4中的特性,所以程序集加载到...,结果str和str1引用了堆中的同一个"xiaochao"字符串,但是我们的代码不能依赖这一行为,因为未来的CLR版本可能会重视这些特性和标志,到时候将不会对程序集元数据中的字面值字符串不进行留用.下面的代码将显示留用字符串...引用改字符串的所有代码都被修改成引用元数据中的同一个字符串.编译器将单个字符串的多个实例合并成一个实例,能显著减少模块的大小.C/C++编译器多年来一直采用这个技术,这个技术被称为"字符串池".

    78020

    .net core 插件式开发

    ,对于类似这样的需求,可以考虑使用插件式的方式搭建框架,以实现更灵活的可拆卸动态增加功能。....net core 中提供了一种热加载外部dll的方式,可以满足该类型的需求 AssemblyLoadContext 流程 1,定义针对系统中所有可插拔点的接口 2,针对接口开发插件/增加默认实现...,值得注意的的是 CopyLocalLockFileAssemblies,表示将所有依赖项生成到生成目录,对于插件中有对其他项目或者类库有引用的这个属性是必须的,Private表示引用的类库为公共程序集...加载到当前应用程序域,静态方法用户获取实现了插件接口的实例 public class PluginLoadContext : AssemblyLoadContext {...().FirstOrDefault(o => o.Location == pluginLocation); //根据程序集的物理位置判断当前域中是否存在该类库,如果不存在就读取

    1.3K20
    领券