27

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.

4
  • 1
    Serious question now: does this static file change from build to build or is it just a file that will never change?
    – splattne
    May 10, 2009 at 8:02
  • Just a crazy thought, but I wonder what would happen if you enabled Shadow Copies on this folder? May 10, 2009 at 13:14
  • This is your sitemap.xml right ? May 10, 2009 at 13:21
  • Yeah, it was our sitemap.xml, but now we just have a MVC route to it and cache the sucker in memory. No more locking! Jun 12, 2009 at 8:01

9 Answers 9

12

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.

3
  • 2
    +1 for process explorer, it may give you some insight into being able to solve the problem if you can see what thread is holding the file handle open May 10, 2009 at 14:50
  • Maybe very useful released locked file programmatically using Sysinternals tools with Powershell, C# or scripts bat-cmd
    – Kiquenet
    Aug 9, 2015 at 8:35
  • I've got IIS to unlock the file or directory simply by trying to copy files into that IIS controlled folder and then viewing the web app in a browser. Sometimes this process unlocks those handles.
    – Marc Noon
    Apr 15, 2016 at 22:04
13

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:

handle c:\weird.file
Something.exe pid: 1000 100: C:\weird.file
Something.exe pid: 1000 101: C:\weird.file

Then you pass it the -c switch to make it close the handle:

handle.exe -c 101 -p 1000 -y
handle.exe -c 100 -p 1000 -y

You might struggle to work that in to a build script without a wrapper program to parse the output but hopefully this will help.

4
  • The mighty Mark Russinovich to the rescue - I'll check this out, but Handle's dire warning of program instability when forcibly closing a handle makes me nervous. May 12, 2009 at 3:47
  • Hopefully any instability will be limited to the AppPool in question. If that's the case, then you can just do a restart of the AppPool after you've released the lock. May 12, 2009 at 7:37
  • @ Jarrod: any luck? Could you post any results, up into your original post, please? i'd love to see what is happening here, behind the scenes.
    – Pure.Krome
    May 13, 2009 at 5:14
  • Maybe very useful released locked file programmatically using Handle with Powershell, C# or scripts bat-cmd and get processes that lock a folder
    – Kiquenet
    Aug 9, 2015 at 8:38
5

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:

C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"
7
  • 1
    No, it's just a static content file in the root directory - updating the question with that info! May 10, 2009 at 7:14
  • 1
    I guess you're using the app_offline.htm during the exection of your build job?
    – splattne
    May 10, 2009 at 7:22
  • I think we've tried recycling manually to no avail, but we'll try it again next time there's a lock (app pools are for .NET, right? probably won't help here). And we used to have the app_offline.htm file created, but it didn't help with the locking - which is why we moved to taking the individual site down. May 10, 2009 at 8:02
  • I'm afraid you're right. I'll test this on one of our servers and come back to you.
    – splattne
    May 10, 2009 at 8:27
  • 1
    @splattne: Recycling the application pool should've removed the handle provided the file was opened by the website. If recycling the pool does not help then my guess is that something else locks the file.
    – pbz
    May 11, 2009 at 15:55
2

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.

1

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.

1
1

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.

1

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.

0

Sure, stop the IIS service. Maybe I'm not understanding something, sorry.

4
  • 2
    If you're stopping the IIS service, you'll take down all web sites...
    – splattne
    May 10, 2009 at 7:52
  • That is the one thing we really want to avoid, as we don't want our CruiseControl.NET site coming down - we click that "Refresh Status" button like madmen during a build to check for success! May 10, 2009 at 8:03
  • Ok, how about building somewhere else first, then deploying over the static file instead of doing everything on that server?
    – Mark Allen
    May 11, 2009 at 3:11
  • isn't that the issue here? Nobody said the file was being modified by software on the server itself. Aug 9, 2012 at 1:28
0

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.

1
  • No, we're not able to do anything to the file until IIS is restarted. May 11, 2009 at 6:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .