views:

701

answers:

3

I would like to update a dll for a server process without stopping the service. How do I do that? A bit like how asp.net automatically picks up new dlls placed in the bin folder.

+8  A: 

Asp.Net uses a technique called shadow copy

If you copy an updated dll into an application’s bin subdirectory, the ASP.NET runtime recognizes there is new code to execute. Since ASP.NET cannot swap the dll into the existing AppDomain , it starts a new AppDomain. The old application domain is “drain stopped”, that is, existing requests are allowed to finish executing, and once they are all finished the AppDomain can unload. The new AppDomain starts with the new code and begins taking all new requests.

Typically, when a dll loads into a process, the process locks the dll and you cannot overwrite the file on disk. However, AppDomains have a feature known as Shadow Copy that allows assemblies to remain unlocked and replaceable on disk.

The runtime initializes ASP.NET with Shadow Copy enabled for the bin directory. The AppDomain will copy any dll it needs from the bin directory to a temporary location before locking and loading the dll into memory. Shadow Copy allows us to overwrite any dll in the bin directory during an update without taking the web application offline.

Gulzar
Take a look at episode #5 of Hibernating Rhinos: http://ayende.com/hibernating-rhinos.aspx
asgerhallas
+2  A: 

In addition to Gulzar's answer:

If your service is just directly referencing the DLL's you'll need to re-design the service a bit to utilise AppDomains and the ShadowCopy capabilities to take advantage of this feature.

We do something like this where the service is just a shell/host process. All functionality is loaded into separate app domains as an when required.

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

Kev
A: 

When a process has loaded a dll it is not possible to change it.

IIS does not keep a DLL loaded in memory when it is not being used (affected by the Cache property) and i assume the same is the case with ASP.NET. If you follow the same strategy you could update your dlls too.

However if your dlls are being used, you should have a way to tell your server process to unload all your dlls.

For this to happen the server process must load all the DLLS using the LoadLibrary calls such that it can unload them when it receives a communication asking it to do so.

Communicating with the server process can be done by creating a globally available named event that can be accessed by the new program and used to signal the running process that an update is about to happen. (You could also think of other variations of doing this).