During our production builds, a very large (10 megabyte) static content file in the root directory will sometimes be locked by IIS and cannot be deleted by the clean task. This is presumably because it is being actively served to one or more clients at the time.
The build process stops the website before cleaning via
c:\Windows\System32\inetsrv\appcmd.exe stop site http://oursite.com
However, this does not release the file - we have to restart IIS to get the process to relinquish its lock.
appcmd.exe
allows you to take IIS down completely; we do not want to do this!
Are there any other ways to get IIS to let go of a locked file, without restarting IIS? Simply stopping and starting the individual website is definitely not working to release the file lock.
I use a little tool called "Handle" to do this.
You basically pass it the name of the file that's locked and it tells you what processes are using it:
Then you pass it the -c switch to make it close the handle:
You might struggle to work that in to a build script without a wrapper program to parse the output but hopefully this will help.
There are tools, such as Sysinternal's Process Explorer, that can find and forcibly close file handles, however the state and behaviour of the application (both yours and, in this case, IIS) after doing this is undefined. Some won't care, some will error and others will crash hard.
The correct solution is to take the outage and allow IIS to cleanly release locks and clean up after itself to preserve server stability. If this is not possible, you can either create another site on the same box, or set up a new box with the new content, and move the domain name/IP across to "promote" the new content to production.
I'm not sure if you mean the compilation of aspx files in temporary assemblies. We are using ASP.NET deployment projects, which precompile all aspx/ascx files beforehand.
While copying the binary files from the "publish" to the "bin" folder, we temporary enable a app_offline.htm file which is removed after all assemblies are copied (just a few seconds). This way I never experienced file locks.
EDIT:
You could try to recycle the app pool using appcmd.exe, instead of stopping the web site:
I'm trying this out now: Apparently there could be issues with file locking if you have indexing activated on the directory. http://www.richard-banks.org/2008/04/how-to-fix-problems-with-locked-files.html
This is IIS 6.0 but since this seems to be related to the OS and not IIS it might be the root cause.
Process Monitor should help you with your investigation, here's an example from Mark's blog (the guy that wrote the tool) on how to find the file handle.
You may want to try this Unlocker tool to automate your unlocking at a file handle level.
Not the answer, but a workaround idea in case there is no way to "unlock" that file without restarting IIS server:
What if you build/deploy to an new empty folder and change the website's home directory to that folder? You have to create an new folder name though or switch between two names.
I don't know in which folder that file belongs. If it doesn't have to be in the root folder, you could put it in a newly created folder and create a virtual directory pointing to that folder. So you can keep your standard home directory for the application.
I had the same problem. Now I switched to MSDeploy (Web Deploy), and now I can update the web site reliably without stopping anything. In fact this step is scripted in our automated build tool and it happens all the time without any problems. And it's fast, too.
Sure, stop the IIS service. Maybe I'm not understanding something, sorry.
note: not an expert on windows file locking semantics
Jarrod, are you able to rename the file out of the way. You may also be able to create your new file with a temporary extension, and then rename it over the current file.
If windows file locking semantics work similar to POSIX ones the readers that hold a current read lock on the file, should still continue to serve the old file until they close their read streams, while new readers will open the new file.