在新的AppDomain中加载程序集而不在父AppDomain中加载它

18

我试图将一个dll加载到控制台应用程序中,然后卸载它并彻底删除文件。问题是,在自己的AppDomain中加载dll会在父AppDomain中创建一个引用,因此不允许我销毁dll文件,除非我完全关闭程序。有什么想法可以使这段代码工作吗?

string fileLocation = @"C:\Collector.dll";
AppDomain domain = AppDomain.CreateDomain(fileLocation);
domain.Load(@"Services.Collector");
AppDomain.Unload(domain);

顺便说一下,我尝试了这段代码,但也没有成功

string fileLocation = @"C:\Collector.dll";
byte[] assemblyFileBuffer = File.ReadAllBytes(fileLocation);

AppDomainSetup domainSetup = new AppDomainSetup();
domainSetup.ApplicationBase = Environment.CurrentDirectory;
domainSetup.ShadowCopyFiles = "true";
domainSetup.CachePath = Environment.CurrentDirectory;
AppDomain tempAppDomain = AppDomain.CreateDomain("Services.Collector", AppDomain.CurrentDomain.Evidence, domainSetup);

//Load up the temp assembly and do stuff 
Assembly projectAssembly = tempAppDomain.Load(assemblyFileBuffer);

//Then I'm trying to clean up 
AppDomain.Unload(tempAppDomain);
tempAppDomain = null;
File.Delete(fileLocation); 
2个回答

4
这应该很容易:

namespace Parent {
  public class Constants
  {
    // adjust
    public const string LIB_PATH = @"C:\Collector.dll";
  }

  public interface ILoader
  {
    string Execute();
  }

  public class Loader : MarshalByRefObject, ILoader
  {
    public string Execute()
    {
        var assembly = Assembly.LoadFile(Constants.LIB_PATH);
        return assembly.FullName;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var domain = AppDomain.CreateDomain("child");
      var loader = (ILoader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
      Console.Out.WriteLine(loader.Execute());
      AppDomain.Unload(domain);
      File.Delete(Constants.LIB_PATH);
    }
  }
}

无法工作。当我尝试删除文件时,出现未经授权的访问异常。你测试过你的代码吗? - Wolfgang Roth
@WolfgangRoth - 对我来说它是有效的。如果你有任何具体问题,我建议你提出一个新的问题。 - Ondrej Svejdar
我解决了我的问题:实际上,在调试时,Visual Studio 调试器会自动连接到程序集,并且不会再断开连接。但是,当我在没有调试器的情况下运行或者首先将程序集文件加载到字节数组中时,一切都正常... - Wolfgang Roth

4

好的,我解决了这个问题。显然,如果您调用AppDomain.Load,它将在父AppDomain中注册。因此,答案很简单,根本不需要引用它。以下是一个网站链接,展示了如何正确设置:

https://bookie.io/bmark/readable/9503538d6bab80


添加了新链接到答案。 - JoeBrockhaus
5
新链接也已经失效。 - Mr Bell
链接都已失效。 - Kingpin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接