将程序集加载到子 AppDomain 并释放 dll 文件

Posted

技术标签:

【中文标题】将程序集加载到子 AppDomain 并释放 dll 文件【英文标题】:Load assembly into child AppDomain and releasing dll file 【发布时间】:2011-08-08 16:38:16 【问题描述】:

我有子应用程序域,我想在启动时加载一些 dll 库并发布文件,以便任何人都可以删除它们。

在启动时我会这样做

Loader al = (Loader)domain.CreateInstanceAndUnwrap(
typeof(Loader).Assembly.FullName,
typeof(Loader).FullName);
al.Load(path)

为以下课程。

class Loader : MarshalByRefObject

    internal void Load(string path)
    
        Assembly assembly;
        try
        
            assembly = Assembly.Load(File.ReadAllBytes(path));
        
        catch (Exception)  return; 
    
    internal UseType(string fullyQualifiedTypeName)
    
         Type userType = Type.GetType(fullyQualifiedTypeName);
    

稍后我调用UseType 并获得了正确的类型,但我无法再删除该文件,因为好像子应用程序域已锁定 dll。

基本上我想要实现的是在启动时缓存程序集文件,然后使用GetType调用,以便释放实际的dll文件。

真的有可能实现这样的目标吗?

【问题讨论】:

CreateInstanceAndUnwrap() 也将类型加载到主应用程序域中。这会锁定文件。使用在单独程序集中定义的接口类型。 我可以锁定包含 Loader 的文件。或者 Loader 方法中使用的任何类型都会使其程序集加载到父应用程序域中? 另见:***.com/questions/6480140/… 【参考方案1】:

创建应用程序域时使用卷影副本。这会将 dll 复制到缓存中,任何人都可以与文件系统进行交互。

Topshelf 使用我们的搁置来实现这一点(然后一切都存在于它自己的应用程序域中)-https://github.com/Topshelf/Topshelf/blob/v2.3/src/Topshelf/Model/ShelfReference.cs#L126。

更新:Topshelf 不再执行此操作,而是更新了指向执行此操作的版本的链接。

【讨论】:

没问题,希望对您有所帮助! 是的,它有帮助!如果库来自自定义源,则只需要设置 ShadowCopyDirectories 属性。

以上是关于将程序集加载到子 AppDomain 并释放 dll 文件的主要内容,如果未能解决你的问题,请参考以下文章

C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载

将程序集加载到另一个 AppDomain 和类型检查

如何将带有 dll 的应用程序从内存加载到 AppDomain 中并执行它?

C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载

在不知道类型的情况下将程序集从文件加载到自定义 AppDomain

C#动态加载dll 时程序集的卸载问题