views:

608

answers:

3

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?

A: 

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.

Nate Bross
+6  A: 

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.

pst
Agreed...plus, checking delete rights on every folder before deleting seems like it would be a big performance hit versus handling the occasional exception (provided no delete permissions is the exception instead of the rule).
pjabbott
Thing is that I first get directories, and then call the same method on all of those. Then I check if the directory is empty, and if it is I try to delete it. In other words, it is first a read, and then later maybe a delete depending on if the directory is still empty or not.
Svish
@pjabbott, I guess that is a good point. Maybe I'll just handle the exception instead. Something which I probably should either way...
Svish
+1  A: 

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.

Rubens Farias