views:

1448

answers:

6

Does there exist any way in .Net to check before opening if a file (on a local network drive) is already in use?

+3  A: 

You should try to access it and if it failed, you either don't have required permissions (which you can check with GetAccessControl) or it's locked by another process.

But I don't think there is any reliable measure to distinguish a lock and a permission failure (since you might be able to read the file, but not able to check the permissions). Even Windows' error message says you either don't have permission or it's being used by another process.

You can use WMI CIM_DataFile class to query InUseCount for a specified data file.

If you're looking for a programmatical equivalent to lsof utility in Linux, to find out all open files by a given local process, you could try using Win32_Process WMI class through System.Management namespace. You could issue a WMI query to look up the file name in all open files being used by all local processes too see if it's there or not. Alternatively, you could P/Invoke and use NtQuerySystemInformation API directly to accomplish the same task.

Mehrdad Afshari
What if the file is already open with FileShare.ReadWrite? Then you can still open it without any error on your side, but it is already in use
liggett78
You could try to rename the file... if it was already in use, it would throw an exception.But that wouldn't be a good solution.
Nelson Reis
@Nelson, If you have just read permission for the file, can you do it?! Even if it's not locked, an exception will be thrown.
Mehrdad Afshari
@liggett78, if you try to acquire an exclusive lock (open it exclusively), it'll fail even if it's already open with shared lock.
Mehrdad Afshari
+1  A: 

Use System.IO.File.OpenWrite(path). Surround it in a try/catch block, and if it is already open for writing somewhere else, you will get a System.UnauthorizedAccessException.

Yaakov Ellis
You can open a file for write successfully if another process specified that the file be shared-for-write (FileShare.Write).
liggett78
A: 

The following syntax will help:

FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);

lakshmanaraj
+1  A: 

This will do. FileShare.None as mentioned in MSDN :

None : Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.

File.Open(name, FileMode.Open, FileAccess.Read, FileShare.None);

EDIT : Remember to wrap in a Try/Catch block, and using FileShare.None actually means you want to open the file exclusively.

faulty
+1  A: 
bool CanReadAndWrite(string path)
{
    var perm = new System.Security.Permissions.FileIOPermission(
         System.Security.Permissions.FileIOPermissionAccess.Write |
         System.Security.Permissions.FileIOPermissionAccess.Read,
         path);
    try
    {
         perm.Demand();
         return true;
    }
    catch 
    {
         return false;
    }
}

Checks to see if you can read and write to a file.

AndreasN
Just remember that the file can still be locked after calling this function, but before you try to open it. So there is currently no 100% solution except for trying to Open the file and then handling the exception, if any.
Ash
A: 

In general, you should always avoid relying on file accessibility checks. The reason is that it might be, and then it may change just a couple of cycles before you access it.

Instead, just try to open it and see if you have any errors.

ya23