创建自定义的AppDomain并添加组件到它 [英] Create custom AppDomain and add assemblies to it

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

问题描述

我如何创建一个AppDomain,添加程序集,然后销毁应用程序域?这是我曾尝试:

 静态无效的主要(字串[] args)
    {
        字符串pathToExe = @A:\\用户\\托诺\\桌面\\ ConsoleApplication1.exe中;        AppDomain中myDomain的= AppDomain.CreateDomain(MYDOMAIN);        大会一=的Assembly.Load(System.IO.File.ReadAllBytes(pathToExe));        myDomain.Load(a.FullName); //崩溃了!
    }

我也尝试:

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

我怎么可以添加一个组件在AppDomain。一旦我这样做,我能找到通过反射的方法执行它,然后破坏应用程序域

这是我得到的例外是:


  

无法加载文件或程序集ConsoleApplication1,版本= 1.0.0.0,
  文化=中性公钥= null或它的一个依赖。该
  系统找不到指定的文件。



解决方案

两个快速点:


  1. AppDomain.Load 加载在当前的AppDomain的程序集,而不是 myDomain的(奇怪,我知道)。

  2. AppDomain.Load 加载在加载的背景下,它从应用基础目录解析组件的装配,私人斌路径和GAC。最可能的是,您尝试加载程序集不位于这些位置这也解释了异常的消息。

有关更多信息看看这个回答

加载组件以一个AppDomain的一种方法是通过创建一个MarshalByRef衍生装载机。你需要像这样以避免泄漏类型(和组件)到您的主AppDomain中。这里有一个简单的:

 公共类SimpleAssemblyLoader:MarshalByRefObject的
{
    公共无效负载(字符串路径)
    {
        ValidatePath(路径);        的Assembly.Load(路径);
    }    公共无效LoadFrom(字符串路径)
    {
        ValidatePath(路径);        Assembly.LoadFrom(路径);
    }    私人无效ValidatePath(字符串路径)
    {
        如果(路径== NULL)抛出新的ArgumentNullException(路径);
        如果(!System.IO.File.Exists(路径))
            抛出新的ArgumentException(的String.Format(路径\\{0} \\不存在,路径));
    }
}

和使用这样的:

  //创建加载器(代理)。
VAR assemblyLoader = (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof运算(SimpleAssemblyLoader).FullName);
//在LoadFrom上下文加载程序集。请注意负载情况下将
//不行,除非你正确设置的AppDomain基本目录和私营仓路径。
assemblyLoader.LoadFrom(pathToExe);//做任何你想做的事。//最后卸载的AppDomain。
AppDomain.Unload(myDomain的);

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!            
    }

I have also tried:

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

The exception that I get is:

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.

解决方案

Two quick points:

  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.

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

And use it like that:

//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天全站免登陆