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.

splattne
  • 28,508
  • 20
  • 98
  • 148
Jarrod Dixon
  • 685
  • 2
  • 13
  • 23

9 Answers9

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.

Simon Johnson
  • 405
  • 1
  • 4
  • 9
  • 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. – Jarrod Dixon May 12 '09 at 03: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. – Simon Johnson May 12 '09 at 07: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 '09 at 05: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 09 '15 at 08:38
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.

Greg Work
  • 1,966
  • 12
  • 11
  • 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 – Nick Kavadias May 10 '09 at 14:50
  • Maybe very useful released **locked file** ***programmatically*** using Sysinternals tools with _Powershell_, _C#_ or _scripts bat-cmd_ – Kiquenet Aug 09 '15 at 08: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 '16 at 22:04
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"
splattne
  • 28,508
  • 20
  • 98
  • 148
  • 1
    No, it's just a static content file in the root directory - updating the question with that info! – Jarrod Dixon May 10 '09 at 07:14
  • 1
    I guess you're using the app_offline.htm during the exection of your build job? – splattne May 10 '09 at 07: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. – Jarrod Dixon May 10 '09 at 08:02
  • I'm afraid you're right. I'll test this on one of our servers and come back to you. – splattne May 10 '09 at 08:27
  • I can't reproduce it (IIS 7 on Windows Server 2008). I copied a 30 MB zip file to the server, started a browser download and could delete it. I thought, maybe it's related to compression, so I renamed it to .xml. Same result: I still could delete it while the remote browser was downloading it. :( – splattne May 10 '09 at 12:30
  • Okay, could reproduce it now. Being very fast (I suppose before the file was read to memory?), I deleted the file in Windows Explorer, which removed the file from Explorer's UI, but it was still here. Pressed F5 on Explorer, the file re-appeared. A 2nd delete showed the expected message, that the file was blocked. Process Explorer revealed that the app pool's w3wp.exe process had a file handle open. Recycling the app pool didn't remove the file handle. – splattne May 10 '09 at 12:58
  • 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 '09 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.

Morten
  • 135
  • 1
  • 4
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.

realMarkusSchmidt
  • 540
  • 1
  • 7
  • 16
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.

Nick Kavadias
  • 10,796
  • 7
  • 37
  • 47
  • Cool, I've never used Process Monitor; but every workstation I use immediately gets Process Explorer! http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx – Jarrod Dixon May 12 '09 at 03:51
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.

splattne
  • 28,508
  • 20
  • 98
  • 148
0

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

Mark Allen
  • 474
  • 3
  • 8
  • 2
    If you're stopping the IIS service, you'll take down all web sites... – splattne May 10 '09 at 07: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! – Jarrod Dixon May 10 '09 at 08: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 '09 at 03:11
  • isn't that the issue here? Nobody said the file was being modified by software on the server itself. – FlavorScape Aug 09 '12 at 01: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.

Dave Cheney
  • 18,567
  • 8
  • 49
  • 56