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

C# 创建自定义AppDomain并向其中添加程序集,c#,reflection,assemblies,appdomain,C#,Reflection,Assemblies,Appdomain,如何创建appdomain,向其中添加程序集,然后销毁该应用程序域?这就是我尝试过的: static void Main(string[] args) { string pathToExe = @"A:\Users\Tono\Desktop\ConsoleApplication1.exe"; AppDomain myDomain = AppDomain.CreateDomain("MyDomain"); A

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

    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,版本=1.0.0.0, 区域性=中性,PublicKeyToken=null'或其依赖项之一。这个 系统找不到指定的文件

两个要点:

  • AppDomain.Load
    在当前AppDomain中加载程序集,而不是在
    myDomain
    上加载(奇怪,我知道)
  • AppDomain.Load
    Load
    上下文中加载程序集,该上下文解析来自apps base dir、专用bin路径和GAC的程序集。最可能的情况是,您尝试加载的程序集不在这些位置中的任何一个,这解释了异常消息
  • 有关更多信息,请查看此

    将程序集加载到AppDomain的一种方法是创建MarshallByRef派生的加载程序。您需要这样做以避免将类型(和程序集)泄漏到主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);
    

    将程序集加载到自己的域更容易——因此,不要尝试将程序集推到其他域中,而是考虑在其他域中运行某些代码来加载所需的任何程序集(不要忘记需要预先加载依赖项或正确设置程序集搜索路径)。如果不知道可能是什么,请使用Fuslogvw.exe。并使用AppDomainSetup设置正确的私有路径。您好,我刚刚尝试使用您的建议预加载一些.net程序集,以确定它们是否包含某个接口类实现。但是,与将程序集加载到当前域(工作正常)不同,我无法将它们加载到新创建的AppDomain myDomain中。