创建自定义AppDomain并向其添加程序集

本文关键字:添加 程序集 自定义 AppDomain 创建 | 更新日期: 2023-09-27 18:19:13

如何创建一个应用域,向其中添加程序集,然后销毁该应用域?这是我尝试过的:

    static void Main(string[] args)
    {           
        string pathToExe = @"A:'Users'Tono'Desktop'ConsoleApplication1.exe";
        AppDomain myDomain = AppDomain.CreateDomain("MyDomain");
        Assembly a = Assembly.Load(System.IO.File.ReadAllBytes(pathToExe));
        myDomain.Load(a.FullName); // Crashes here!            
    }

我也试过了:

myDomain.Load(File.ReadAllBytes(pathToExe)); 

如何将程序集添加到应用域。一旦我这样做了,我就可以通过反射找到方法执行它,然后销毁appdomain

我得到的异常是:

无法加载文件或程序集文化=中性,PublicKeyToken=null'或其依赖项之一。的系统无法找到指定的文件。

创建自定义AppDomain并向其添加程序集

两个要点:

  1. AppDomain.Load加载当前AppDomain中的程序集,而不是myDomain上的程序集(很奇怪,我知道)。
  2. AppDomain.LoadLoad上下文中加载一个程序集,它从应用程序的base-dir、private-bin-paths和GAC中解析程序集。最有可能的是,您尝试加载的程序集不位于这些位置中的任何一个,这解释了异常消息。

更多信息请看这个答案

将程序集加载到AppDomain的一种方法是创建一个marshalbyref派生的加载器。您需要这样做来避免将类型(和程序集)泄漏到主AppDomain。下面是一个简单的例子:

public class SimpleAssemblyLoader : MarshalByRefObject
{
    public void Load(string path)
    {
        ValidatePath(path);
        Assembly.Load(path);
    }
    public void LoadFrom(string path)
    {
        ValidatePath(path);
        Assembly.LoadFrom(path);
    }
    private void ValidatePath(string path)
    {
        if (path == null) throw new ArgumentNullException("path");
        if (!System.IO.File.Exists(path))
            throw new ArgumentException(String.Format("path '"{0}'" does not exist", path));
    }
}

像这样使用:

//Create the loader (a proxy).
var assemblyLoader =  (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName);
//Load an assembly in the LoadFrom context. Note that the Load context will
//not work unless you correctly set the AppDomain base-dir and private-bin-paths.
assemblyLoader.LoadFrom(pathToExe);
//Do whatever you want to do.
//Finally unload the AppDomain.
AppDomain.Unload(myDomain);