创建自定义 AppDomain 并向其添加程序集 [英] Create custom AppDomain and add assemblies to it

查看:35
本文介绍了创建自定义 AppDomain 并向其添加程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I create an appdomain, add assemblies to it, then destroy that app domain? This is what I have tried:

    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)); 

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

how can I add an assembly to the appdomain. Once I do that I can find the method via reflection execute it and then destroy the appdomain

我得到的例外是:

无法加载文件或程序集ConsoleApplication1,版本=1.0.0.0,Culture=neutral, PublicKeyToken=null' 或其依赖项之一.这系统找不到指定的文件.

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

推荐答案

两点:

  1. AppDomain.Load 在当前 AppDomain 中而不是在 myDomain 中加载程序集(很奇怪,我知道).
  2. AppDomain.LoadLoad 上下文中加载程序集,该上下文从应用程序基目录、private-bin-paths 和 GAC 解析程序集.最有可能的是,您尝试加载的程序集未位于解释异常消息的任何这些位置.
  1. AppDomain.Load loads an assembly in the current AppDomain and not on myDomain (weird, I know).
  2. AppDomain.Load loads an assembly in the Load context, which resolves assemblies from the apps base-dir, the private-bin-paths and the GAC. Most probably, the assembly you try to load is not located in any of these locations which explains the exception message.

有关更多信息,请查看此答案.

For more info have a look at this answer.

将程序集加载到 AppDomain 的一种方法是创建一个 MarshalByRef 派生的加载器.您需要这样的东西来避免将类型(和程序集)泄漏到您的主 AppDomain.这是一个简单的:

One way to load assemblies to an AppDomain is by creating a MarshalByRef-derived loader. You need something like this to avoid leaking types (and assemblies) to your main AppDomain. Here's a simple one:

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);

这篇关于创建自定义 AppDomain 并向其添加程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆