1

我有一个由几个服务组件组成的COM+ 应用程序。

其中一个按需实例化从 dll 到 Activator.CreateInstance(pluginType, args);. 该类型本身不是服务组件,它仅包含组件知道的某些接口的实现。

我对实例化本身没有问题,问题是 dll 被 .dll 锁定dllhost.exe,如果可能的话,我希望能够在不关闭 COM+ 应用程序的情况下替换它。

是否有可能在不关闭 COM+ 应用程序的情况下以某种方式解锁 dll?

或者从另一个角度来看,有没有一种方法可以以编程方式卸载 dll 来解锁它?

注意:该 dll 与其他 dll 一起位于 COM+ 应用程序根目录中。

4

2 回答 2

1

这不是 COM+ 的特定问题,它在 Windows 上是通用的,并且是其工作方式的基础。从可执行文件(exe 或 dll)加载代码是由 Windows 为可执行文件创建内存映射文件完成的。仅当页面错误需要实际读取文件并将代码映射到 RAM 时,才会从文件中读取代码。当其他进程竞争 RAM 并且代码未映射时,这种情况会反复发生。

MMF 将锁定文件。必需,以便在将代码映射到 RAM 时无法修改文件。

对此没有解决方法,加载了 DLL 的进程必须终止,或者必须在释放锁之前合作并卸载 DLL。充其量您可以在使用文件时重命名该文件,否则不会影响该过程。

于 2012-10-25T09:07:35.833 回答
1

加载的模块在 windows 中被引用计数。在 Windows 中,我们有 loadLibrary 和 freelibrary。如果调用了 freelibrary 并且引用计数为零,则 dll 将被卸载并可以自由替换、删除等。

在 .NET 中,尽管一旦将程序集加载到 appDomain 中,它就会一直存在,直到 appdomain 终止(除非反射发出可收集的程序集)。如果您要生成另一个 appdomain 并在新的 appdomain 死亡时在此处创建实例,则程序集将被卸载。

Asp.net 做了一些叫做影子缓存的事情。Asp.net,您可以随时替换 dll,而无需终止工作进程。他们通过不加载 bin 文件夹中的 dll 来做到这一点,而是将它们复制到单独的位置并从那里加载到单独的 appdomain 中。他们观察 bin 文件夹,当发生更改时,他们会杀死 appdomain,将 dll 复制到 temp 文件夹,然后创建一个新的 appdomain。

影子复制程序集 http://msdn.microsoft.com/en-us/library/ms404279.aspx

于 2012-10-25T09:27:25.387 回答