Here's what you could do:
1) You could test if you have rights to access to the file before trying to access to your file. From this SO thread, here is a method that should return true if user has Write
rights (i.e. when right-clicking on a file -> property -> security). This covers your point (2) for unappropriated access privileges (do note that there is maybe something more robust/error-proof to get this information than the code below):
public static bool HasWritePermissionOnFile(string path)
{
bool writeAllow = false;
bool writeDeny = false;
FileSecurity accessControlList = File.GetAccessControl(path);
if (accessControlList == null)
{
return false;
}
var accessRules = accessControlList.GetAccessRules(true, true, typeof(SecurityIdentifier));
if (accessRules == null)
{
return false;
}
foreach (FileSystemAccessRule rule in accessRules)
{
if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
{
continue;
}
if (rule.AccessControlType == AccessControlType.Allow)
{
writeAllow = true;
}
else if (rule.AccessControlType == AccessControlType.Deny)
{
writeDeny = true;
}
}
return writeAllow && !writeDeny;
}
2) Do try to instantiate your FileStream
, and catch exceptions:
try
{
string file = "...";
bool hasWritePermission = HasWritePermissionOnFile(file);
using (FileStream fs = new FileStream(file, FileMode.Open))
{
}
}
catch (UnauthorizedAccessException ex)
{
// Insert some logic here
}
catch (FileNotFoundException ex)
{
// Insert some logic here
}
catch (IOException ex)
{
// Insert some logic here
}
In your case (3) (file requires elevation), UnauthorizedAccessException
is thrown.
In your case (1) (file is locked by another process), IOException
is thrown. You can then check the HRESULT of the exception for more details:
catch (IOException ex)
{
// Gets the HRESULT
int hresult = Marshal.GetHRForException(ex);
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
// for system error code
switch (hresult & 0x0000FFFF)
{
case 32: //ERROR_SHARING_VIOLATION
Console.WriteLine("File is in use by another process");
break;
}
}
Now you should be able to distinguish your 3 use cases.