1

How to distinguish cases when file operation failed due to file lock and lack of permissions?

user626528
  • 13,999
  • 30
  • 78
  • 146

3 Answers3

4

As per my answer here: Is there a way to check if a file is in use?

const int ERROR_SHARING_VIOLATION = 32;
const int ERROR_LOCK_VIOLATION = 33;

private static bool IsFileLocked(Exception exception)
{
    int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
}

...

FileStream stream = null;
try
{
stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException ex)
{
   if (IsFileLocked(ex))
   {
    // you know the file is locked
   } 
}
catch (ArgumentNullException ex)
{
    HandleException(ex);
}
catch (SecurityException ex)
{
    HandleException(ex);
}
catch (ArgumentException ex)
{
    HandleException(ex);
}
catch (ObjectDisposedException ex)
{
    HandleException(ex);
}
catch (UnauthorizedAccessException ex)
{
    // you know you dont have permission to the file
    HandleException(ex);
}
catch (Exception ex) 
{
}
Community
  • 1
  • 1
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
2

Better you can catch the IOException instead of UnauthorizedAccessException. Then process it accordingly.

 try
 {
     File.Open(_fileName, FileMode.Open, fileAccess, Fileshare.None); 
 }
 catch (IOException e)
 {
     if (!IsFileLocked(e))
         throw;
 }

private static bool IsFileLocked(IOException exception)
{
    int errorNum = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorNum == 32 || errorNum == 33;
}

This way you can check FileLocked exception. Same way try out for Access denied exception by checking the appropriate Error Number.

Santosh Panda
  • 7,235
  • 8
  • 43
  • 56
  • The code I call throws UnauthorizedAccessException rather than IOException. – user626528 Jun 13 '13 at 09:11
  • @user626528 Is it important for us to know what your code is? Perhaps different code would lead to `IOException` being thrown. – David Heffernan Jun 13 '13 at 09:30
  • As per MSDN link : http://msdn.microsoft.com/en-us/library/system.io.file.delete.aspx UnauthorizedAccessException occurs when the caller does not have the required permission. While IOException occurs when the specified file is in use. – Santosh Panda Jun 13 '13 at 09:46
  • However, I'm getting UnauthorizedAccessException when I'm trying to delete file which is in use (it's an exe file and application haven't stopped yet). – user626528 Jun 13 '13 at 09:48
1

You can read the ACL from the file using GetFileSecurity, get a handle to the process token using OpenProcessToken and then check for the access you want using AccessCheck.

To the best of my knowledge, sharing rules never prevent you from reading the security, so if you get an access denied at that point it should be safe to assume that you don't have permission to access the file. (Strictly speaking, you might have permission to do other things but not to read the ACL, but that would be a rare edge case.)

If AccessCheck says that you have access but you get access denied when opening the file, it should be safe to assume it's a sharing violation. Again, there may be edge cases, such as if the permissions are being changed at the same time you're looking at them, but that should be rare.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158