一尘不染

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

c#

我想加载到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

无法加载文件或程序集’MyDll,版本= 1.0.0.0,文化=中性,PublicKeyToken =空’或其依赖项之一。该系统找不到指定的文件。

我认为关键部分是 其依赖项之一

好吧,我之前要做 domain.Load(AssemblyName.GetAssemblyName(path));

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

但是FileNotFoundException再次出现在另一个(引用的)程序集上。

如何递归加载所有引用?

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


阅读 429

收藏
2020-05-19

共1个答案

一尘不染

您需要先调用,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而是使用加载任意程序集文件-
但请注意,如果执行此操作,则需要自己加载所有依赖项。

2020-05-19