Question

I loop through a bunch of directories recursively. Some of them (like D:\$RECYCLE.BIN\S-1-5-20) give me a System.UnauthorizedAccessException. I suppose that I can just catch it and move on, but I would rather figure that out in advance.

So, when I have a DirectoryInfo object. How can I see if I am allowed to GetDirectories() and possibly Delete() it?

Was it helpful?

Solution

If you intend to delete it, try to delete it and then proceed (handling the exception as appropriate).

If you perform a check-and-then-delete-if-should-be-able-to-delete there is the chance of a race condition on the filesystem, however slight. This applies to most all file/directory access operations. Most filesystem operations are designed to be atomic and moving this logic into user code conflicts this atomicity and one would still need to handle a possible exception being raised.

OTHER TIPS

I built following code. Please, see if it helps:

//using System.IO;
//using System.Security.AccessControl;
//using System.Security.Principal;

string[] directories = Directory.GetDirectories(
    Path.Combine(Environment.CurrentDirectory, @"..\.."), 
    "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
    DirectoryInfo info = new DirectoryInfo(directory);
    DirectorySecurity security = info.GetAccessControl();
    Console.WriteLine(info.FullName);
    foreach (FileSystemAccessRule rule in 
             security.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference = {0}", rule.IdentityReference);
        Console.WriteLine("\tInheritanceFlags  = {0}", rule.InheritanceFlags );
        Console.WriteLine("\tPropagationFlags  = {0}", rule.PropagationFlags );
        Console.WriteLine("\tAccessControlType = {0}", rule.AccessControlType);
        Console.WriteLine("\tFileSystemRights  = {0}", rule.FileSystemRights );
        Console.WriteLine();
    }
}

Result:

D:\Projects\ConsoleApplication1\bin
    IdentityReference = BUILTIN\Administrators
    InheritanceFlags  = ContainerInherit, ObjectInherit
    PropagationFlags  = None
    AccessControlType = Allow
    FileSystemRights  = FullControl

Note that IdentityReference and FileSystemRights properties; probably you should test your current ACL against them before trying to delete a directory.

I believe you will need to write your own GetDirectories() method; that recursivly gets the ones inside of it.

This Microsoft Article has a good article on how to do it, with a bit of work you can clean it up to use Generic Lists and make it fit your solution.

Simply put, System.IO.Directory.GetDirectories() will fail every time it gets one of those exceptions.

Code roughly like this (copied from above) should get you started

    List<String> directories = new List<String>();
    void DirSearch(string sDir) 
    {
        try 
        {
            foreach (string d in Directory.GetDirectories(sDir)) 
            {
                //foreach (string f in Directory.GetFiles(d, txtFile.Text)) 
                //{
                //    
                //}
                // use this to search for files recursivly.
                directories.Add(d);
                DirSearch(d);
            }
        }
        catch (System.Exception excpt) 
        {
            Console.WriteLine(excpt.Message);
        }
    }

Once you have your list of directories, you can then perform operations on them, with some mods the above method should ensure you have read permissions on anything in the list.

I found this while trying to solve the problem...

Seems related, but pretty unmaintained code, I did not try it

http://technolog.nl/blogs/eprogrammer/archive/2009/06/18/Howto_3A00_-Properly-use-the-AccessCheck-API.aspx

regards

Mario

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top