在不停止服务的情况下更新dll

时间:2008-10-22 16:30:51

标签: .net windows dll windows-services

我想在不停止服务的情况下更新服务器进程的dll。我怎么做? 有点像asp.net如何自动获取放在bin文件夹中的新dll。

3 个答案:

答案 0 :(得分:21)

Asp.Net使用一种名为shadow copy

的技术

如果将更新的dll复制到应用程序的bin子目录中,ASP.NET运行时会识别出要执行的新代码。由于ASP.NET无法将dll交换到现有的AppDomain,因此它启动了一个新的AppDomain。旧的应用程序域是“排水停止”,即允许现有请求完成执行,一旦完成它们,AppDomain就可以卸载。新的AppDomain以新代码开始,并开始接受所有新请求。

通常,当dll加载到进程中时,进程会锁定dll,并且您无法覆盖磁盘上的文件。但是,AppDomains具有称为卷影复制的功能,允许程序集在磁盘上保持解锁和可替换状态。

运行时使用为bin目录启用的Shadow Copy初始化ASP.NET。在锁定并将dll加载到内存之前,AppDomain会将所需的任何dll从bin目录复制到临时位置。 Shadow Copy允许我们在更新期间覆盖bin目录中的任何dll,而无需使Web应用程序脱机。

答案 1 :(得分:2)

除了Gulzar的回答:

如果您的服务只是直接引用DLL,您需要重新设计一下该服务,以利用AppDomains和ShadowCopy功能来利用此功能。

我们做这样的事情,服务只是一个shell / host进程。所有功能都会根据需要加载到单独的应用程序域中。

http://blogs.msdn.com/junfeng/archive/2004/02/09/69919.aspx

答案 2 :(得分:-2)

当进程加载了一个dll时,无法更改它。

IIS没有在内存中加载DLL(affected by the Cache property),并且我假设ASP.NET的情况也是如此。如果您遵循相同的策略,您也可以更新您的dll。

但是,如果您的dll正在使用,您应该有办法告诉您的服务器进程卸载所有dll。

为此,服务器进程必须使用LoadLibrary调用加载所有DLLS,以便在收到要求它执行此操作的通信时可以卸载它们。

可以通过创建一个全局可用的命名事件来完成与服务器进程的通信,该事件可以被新程序访问并用于通知正在运行的进程即将发生更新。 (你也可以想到这样做的其他变化)。