2008-10-22 39 views
11

我想在不停止服務的情況下更新服務器進程的DLL。我怎麼做? 有點像asp.net自動拾取放置在bin文件夾中的新dll。更新DLL而不停止服務

+0

您的服務用什麼環境/語言編寫? Win32和.NET之間有很大的區別,當涉及到這個問題的解決方案時... – mdb 2008-10-22 16:32:53

+0

這是一個.net應用程序。 – Matt 2008-10-22 16:36:54

回答

21

Asp.Net使用一種稱爲shadow copy

如果複製更新的DLL到應用程序的bin子目錄技術,ASP.NET運行時承認有新的代碼來執行。由於ASP.NET不能將dll交換到現有的AppDomain中,因此它會啓動一個新的AppDomain。舊的應用程序域是「排空停止」,也就是說,現有的請求被允許完成執行,並且一旦完成,AppDomain可以卸載。新的AppDomain以新代碼開始並開始接受所有新請求。

通常,當一個DLL加載到進程中時,該進程會鎖定該DLL並且無法覆蓋該磁盤上的文件。但是,AppDomain具有一種稱爲卷影副本的功能,允許程序集在磁盤上保持解鎖狀態和可替換狀態。

運行時爲bin目錄啓用Shadow Copy初始化ASP.NET。 AppDomain會將所需的所有dll從bin目錄複製到一個臨時位置,然後鎖定並將dll加載到內存中。 Shadow Copy允許我們在更新期間覆蓋bin目錄中的任何dll,而無需使Web應用程序脫機。

2

除了古勒扎爾的回答是:

如果你的服務僅僅是直接引用的DLL的,你需要重新設計的服務一點利用的AppDomain和影拷貝功能,利用這個功能的優勢。

我們這樣做,其中服務只是一個shell/host進程。根據需要將所有功能加載到單獨的應用程序域中。

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

-2

當一個過程已經加載的DLL,不可能改變它。

當IIS沒有被使用時,IIS不會在內存中加載DLL(affected by the Cache property),並且我假設ASP.NET的情況也是如此。如果你遵循同樣的策略,你也可以更新你的dll。

但是,如果你正在使用你的DLL,你應該有辦法告訴你的服務器進程卸載所有的DLL。

要發生這種情況,服務器進程必須使用LoadLibrary調用加載所有的DLLS,以便它在接收到要求這樣做的通信時卸載它們。

與服務器進程通信可以通過創建一個全局可用的命名事件來完成,該命名事件可以被新程序訪問並用於向正在運行的進程發送即將發生更新的信號。 (你也可以考慮這樣做的其他變化)。