开发者

C#: How to check if I can read and/or delete a directory

开发者 https://www.devze.com 2022-12-09 06:30 出处:网络
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开发者_如何

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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号