Ok, so I have searched in many places for the answer to this question, but I'm open to any links if I missed something obvious.
I am interested in producing reasonable error messages to the user when they attempt to open a particular file, but for whatever reason the program cannot access that file. I would like to distinguish between the following cases:
I am using a FileStream object. I have looked at the msdn documentation for instantiating a FileStream, and it is not at all clear to me which Exception does what for the above, and how to distinguish between them. I admit that my experience with Windows programming is limited, so I may be missing something obvious. My apologies if so.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With