9

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

    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。一旦我这样做了,我可以通过反射找到方法执行它,然后销毁 appdomain

我得到的例外是:

无法加载文件或程序集“ConsoleApplication1,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。

4

1 回答 1

11

两个快速点:

  1. AppDomain.Load在当前的 AppDomain 中加载程序集,而不是在myDomain(奇怪,我知道)。
  2. AppDomain.Load在上下文中加载程序Load集,该程序集从应用程序基目录、私有二进制路径和 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);
于 2013-06-26T15:19:39.303 回答