c# - 如何使用所有引用递归地将程序集加载到 AppDomain?

标签 c# .net reflection assemblies appdomain

我想加载到一个新的 AppDomain 一些具有复杂引用树的程序集(MyDll.dll -> Microsoft.Office.Interop.Excel.dll -> Microsoft.Vbe.Interop.dll -> Office.dll -> stdole.dll)

据我所知,当程序集被加载到 AppDomain 时,它的引用不会自动加载,我必须手动加载它们。 所以当我这样做时:

string dir = @"SomePath"; // different from AppDomain.CurrentDomain.BaseDirectory
string path = System.IO.Path.Combine(dir, "MyDll.dll");

AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
setup.ApplicationBase = dir;
AppDomain domain = AppDomain.CreateDomain("SomeAppDomain", null, setup);

domain.Load(AssemblyName.GetAssemblyName(path));

并得到FileNotFoundException:

Could not load file or assembly 'MyDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

我认为关键部分是它的一个依赖项

好的,我在 domain.Load(AssemblyName.GetAssemblyName(path)); 之前执行下一步

foreach (AssemblyName refAsmName in Assembly.ReflectionOnlyLoadFrom(path).GetReferencedAssemblies())
{
    domain.Load(refAsmName);
}

但在另一个(引用的)程序集上再次遇到 FileNotFoundException

如何递归加载所有引用?

我必须在加载根程序集之前创建引用树吗?如何在不加载程序集的情况下获取程序集的引用?

最佳答案

在您的代理对象将在外部应用程序域中执行之前,您需要调用 CreateInstanceAndUnwrap

 class Program
{
    static void Main(string[] args)
    {
        AppDomainSetup domaininfo = new AppDomainSetup();
        domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
        Evidence adevidence = AppDomain.CurrentDomain.Evidence;
        AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence, domaininfo);

        Type type = typeof(Proxy);
        var value = (Proxy)domain.CreateInstanceAndUnwrap(
            type.Assembly.FullName,
            type.FullName);

        var assembly = value.GetAssembly(args[0]);
        // AppDomain.Unload(domain);
    }
}

public class Proxy : MarshalByRefObject
{
    public Assembly GetAssembly(string assemblyPath)
    {
        try
        {
            return Assembly.LoadFile(assemblyPath);
        }
        catch (Exception)
        {
            return null;
            // throw new InvalidOperationException(ex);
        }
    }
}

此外,请注意,如果您使用 LoadFrom,您可能会遇到 FileNotFound 异常,因为程序集解析器将尝试在 GAC 中查找您正在加载的程序集或当前应用程序的 bin 文件夹。使用 LoadFile 来加载任意程序集文件——但请注意,如果您这样做,您将需要自己加载任何依赖项。

关于c# - 如何使用所有引用递归地将程序集加载到 AppDomain?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/658498/

相关文章:

c# - 单声道反序列化问题

c# - 显示数据库中的分层数据?

c# - 在Web API中保存图像时无法解析 "A generic error occurred in GDI+"

C# Winform 尺寸因分辨率降低而减小

c# - 通过动态推断泛型类型。反射

c# - System.StackOverflowException ,何时使用 get set 属性?

c# - sc.exe如何设置对windows服务的描述?

c# - 如何创建动态数量的对象?设计模式帮助

c# - 当属性是委托(delegate)类型时,如何在 C# 中使用反射设置属性值?

go - 调用方法属于struct的字段