views:

172

answers:

1

I have some code that has thrown the following exception:

System.IO.IOException: The process cannot access the file 'MyFileName' because it is being used by another process.
   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
   at System.IO.Directory.Delete(String path, Boolean recursive)
   at MyCodeSomewhere...

Typically I know this to mean I've had an exception somewhere and not tidied up the relevant (e.g.) StreamReader.

Occasionally (only occasionally, typically it's my fault) I get the situation where it's something outside my program has a lock on the file instead (such as my text editor, which is still my fault, but less nasty than a bug caused by me not tidying up after myself).

Is there a technique I can programmatically use to detect which process is causing the file to be unavailable?

  • Is it my process?
  • Is it another process on this machine? If so what's it's name
  • Is it being accessed by a remote computer via file share? If so do I have any chance of finding out relevant information?

What would go in the method GetProcessNameCausingMeGrief?

catch (IOException ioEx)
{ 
    string processName = GetProcessNameCausingMeGrief(ioEx);
    if (processName == Process.GetCurrentProcess())
    {
        throw new ApplicationException("Oops, this code still has it's own file locked", ioEx);
    }
    throw;
}
+1  A: 

Well it is definitely hard to do. It is possible to read list of opened handles, but when you need to get process name by opened handle, you need access to kernel memory (ms design flaw). That is why programs like Unlocker rely on specially written driver (and have problems with older systems, x64 systems and so on).

However if you are working under Vista, then you can use a trick and get process that locks your files by using Restart Manager. Read more here (Restart Manager and Generic Method Compilation).

Update: There is a way to detect which program is opened particular file on Windows XP. Some programs (although small amount of them, I know only about ms office) put references into global running object table, so you can extract such information. This method is tricky, and as I say earlier very few programs do this, but still this is an option.

Here you can find FileLocker class that notify windows explorer about used file. You need to reverse logic from this class to find program that used particular file.

arbiter