views:

993

answers:

8

Hi,

In C#, System.IO.File.Delete(filePath) will either delete the specified file, or raise an exception. If the current user doesn't have permission to delete the file, it'll raise an UnauthorizedAccessException.

Is there some way that I can tell ahead of time whether the delete is likely to throw an UnauthorizedAccessException or not (i.e. query the ACL to see whether the current thread's identity has permission to delete the specified file?)

I'm basically looking to do:

if (FileIsDeletableByCurrentUser(filePath)) {
    /* remove supporting database records, etc. here */
    File.Delete(filePath);
}

but I have no idea how to implement FileIsDeletableByCurrentUser().

+5  A: 

Take a look at this article - http://www.codeproject.com/KB/files/UserFileAccessRights.aspx

adatapost
After looking for an answer to this same question several times over the years, this is the only solution I've seen that doesn't use a try/catch, so it's technically the answer to the question. It looks like a lot of code for what needs to be done, but wrapped in a class that can be reused in multiple project, this is promising.
David Stratton
Just curious - this looks to catch file access permissions based on a user account. Would this catch situations where a file is in use by another process?
David Stratton
But what about if the file is open by another process? Looking and checking permissions still won't 100% guarantee that the file can actually be deleted.
Rippo
That's the sort of thing I was after - but after reading the other responses and the linked code, I actually agree that a try/catch approach, probably combined with a database transaction that can be rolled back if the file delete fails, is a better approach. Thanks for the answer, though - you're right, it does look promising!
Dylan Beattie
+10  A: 

Have you tried System.IO.File.GetAccessControl(filename) it should return a FileSecurity with information about the permissions for that file.

Dale Halliwell
A: 

Of course you can check ReadOnly flags using System.IO and probably ACL security on the file combined with the current user too, but like Mehrdad writes in his comment it would never be full-proof in all cases. So you would need exception handling for the exceptional case at all times (even if its just a top-level catch-all, that logs/shows an "unexpected problem" and kills your application).

peSHIr
A: 

As stated above. Lookup the file permissions and compare with the user who is running the application.

You could always use this aproach as well

bool deletemyfile()
{
try
{
...delete my file
return true;
}
catch
{
return false;
}
}

if it returns false you know it failed if it returns true then.. it worked and file is gone. Not sure what you're after exactly but this was the best I could think of

Jonas B
+2  A: 

Strictly speaking, an UnauthorizedAccessException means that the path is a directory, so you can use a System.IO.Path.GetFileName(path) type command and catch the argument exception.

But if you want a more holistic solution, use System.IO.File.GetAccessControl as mentioned by Dale Halliwell

Tim Joseph
A: 

You should get the access control list (ACL) of that file.

But this doesn't necessarily mean you could actually delete it because the readonly flag could still be set or another program has locked the file.

codymanix
A: 

Seems like it would be easier to do things in the order of:

  1. Get whatever information you need about the file in order to do the other parts (delete database data, etc)
  2. Try to delete the file
  3. If you successfully delete the file, then carry out the rest of the "cleanup" work. If you don't successfully delete it, return/handle the exception, etc.
BBlake
+6  A: 

The problem with implementing FileIsDeletableByCurrentUser is that it's not possible to do so. The reason is the file system is a constantly changing item. It between any check you make to the file system and the following operation any number of events can and will happen. Including ...

  • Permissions on the file could change
  • The file could be deleted
  • The file could be locked by another user / process
  • The USB key the file is on could be removed

The best function you could write would most aptly be named FileWasDeletableByCurrentUser.

JaredPar
Voted up because your proposed function name is both humorous and insightful.
Dylan Beattie