Friday 16 July 2010

Patching files in the GAC, IIS, and the windowa\assembly\temp folder

We keep hitting the same odd problem on our dev server (a VM) when updating (patching) existing dll’s that are resident in the GAC…

The issue is that despite deleting the old file and then copying in the new file (typical patch), then re-starting the host, the change cannot be seen, or worse you get a “missing method” exception etc.

The cause of this appears to be associated with to the way Fusion works when an update is applied to a dll which is held by a long running process, say Biztalk or IIS…

Fusion appears to allow the old version of the GAC file to be removed (either because you’ve asked to remove it as a “step1” or because you simply dropping the new version in “over the top”) but to do so it must deal with the existing file, if it finds that something is still using the old version (a lock exists) it moves the old version to a “temp” folder, before moving the new version into the correct folder… It will try and clean up this temp folder later.


See here for more info



However this shouldn’t (in itself) cause us any problems, though it’s a good thing to be aware of…it’s supposed to work that way and it’s good.

Specifically our issues (and in the past we solved this sort of thing by “re-booting” the server) appear to be with the host which is using the file you’re trying to update, today on our dev server that has been IIS.

When you stop IIS it appears to leave some instances of w3wp (the worker host process, that runs the service/web site) running; using procexp (process explorer from sysinternals) you can see these host instances still have “file handles” pointed at the old version of the dll(s) in question, even though you can also see the new version(s) loaded.

Simply, the trick on our server has been to “iisreset /stop” twice… on the second time the w3wp processes die and the handles are released, when iis is started and a test made, the references to the old dll disappear and your code works.

I am guessing this could (and probably has for us previously) applied to Biztalk hosts. You can then clear the temp files yourself, or let fusion clear them out automatically later.

So in summary, you can “patch” files in the GAC but unless all old processes are unloaded (as you might expect) your old file will still be used, and worse a “hard” copy will exist somewhere on disk!

Temp folders:
c:\windows\assembly\tmp\
c:\windows\assembly\temp\
C:\WINDOWS\microsoft.net\Framework\v2.0.50727\Temporary ASP.NET Files\

** Note: The GAC files in question are strong named, but the new versions are differentiated by FILE VERSION ONLY, not assembly version. So the full name / qualified name of the dll is the same! **