The World’s Leading Microsoft .NET Magazine
   
 
timstall

Donate Today!

Search Box

 

Calendar

««Sep 2010»»
SMTWTFS
    1234
567891011
12131415161718
19202122232425
2627282930

My RSS Feeds








Mailing List

Most Popular Tags

                                                           

Killing the file handles, but not the process (from the command line)

posted Monday, 23 February 2009

Most developers have come across that annoying error where you try to delete or rename an innocent file, only to be  rebuffed with "Access denied, another process is accessing this file." For example, you'll get this type of error if you create a text file, open it in Microsoft Word, and then try to delete the file. This happens for all sorts of things - whether it's a process that didn't clean up after itself (perhaps from an unexpected crash), or something like IIS that locks certain website directories. While PSTool's ProcessExplorer GUI is great for finding what process is locking the file, what if you just want to find the handle, and kill it - from the command line?

Note that there's s a difference between the process, and the handle that that process has on the file. For example, if you want to delete a website that IIS is locking, you could shutdown or kill IIS (i.e. the process itself), but say you want to leave IIS running? Killing just the handle would leave the process intact, while allowing you control of the file again.

A useful tool for this is the (free) PsTools Handle.exe. From the command line, you can query all handles to a file, and then you can delete those handles. For example, this will find all handles on the given directory:

handle.exe C:\MyFolder

And returns something like so:

inetinfo.exe pid: 1696 3DC: C:\MyFolder\MySubfolder
inetinfo.exe pid: 1696 3E0: C:\MyFolder

You can then use this info to close the handles (one-by-one), without killing the process by passing in the "-c" switch, along with the handle id (in hex), and the process id, and the "-y" switch to confirm the delete.

handle.exe -c 3DC -p 1696 -y
handle.exe -c 3E0 -p 1696 -y

You could glue these two steps together into one by calling System.Diagnostics.Process to run the first command, parse its output, and then use that to create the parameters for the second command.

I'm sure there are more elegant ways (perhaps direct C++ calls, or even some special method in the .Net Framework), and I'm all ears to any, but this approach will get the job done.

tags:  

links: digg this    technorati    




1. F left...
Friday, 14 May 2010 10:43 am

Maybe this will help someone. Close all handles to this folder:

for /f "skip=5 tokens=3,4 delims=: " %i in ('handle c:\temp\userscript') do @handle -c %j -p %i -y


2. Robert left...
Thursday, 22 July 2010 1:50 pm

But unfortunatley, when I use System.Diagnostics.Process to create a process to call handle.exe and kill the file handle, it creates a handle to a named pipe that does not go away until my program shuts down, so I'm still in the same boat that I was in before (file handles not getting closed and my program running out of resources)