【问题标题】:C#: How to check if I can read and/or delete a directoryC#:如何检查我是否可以读取和/或删除目录
【发布时间】:2010-12-08 22:02:21
【问题描述】:

我递归地遍历一堆目录。其中一些(例如D:\$RECYCLE.BIN\S-1-5-20)给我一个System.UnauthorizedAccessException。我想我可以抓住它并继续前进,但我宁愿提前弄清楚。

所以,当我有一个DirectoryInfo 对象时。如何查看我是否被允许GetDirectories() 和可能Delete()

【问题讨论】:

    标签: c# access-control directory


    【解决方案1】:

    如果您打算删除它,请尝试将其删除,然后继续(适当处理异常)。

    如果您执行检查然后删除,如果应该删除,则文件系统上可能会出现竞争条件,无论多么轻微。这适用于大多数文件/目录访问操作。大多数文件系统操作都被设计为原子性的,并且将此逻辑移动到用户代码中会与这种原子性冲突,并且仍然需要处理可能引发的异常。

    【讨论】:

    • 同意...另外,在删除之前检查每个文件夹的删除权限似乎与处理偶尔的异常相比对性能有很大影响(前提是没有删除权限是异常而不是规则)。
    • 事情是我首先获取目录,然后在所有这些上调用相同的方法。然后我检查目录是否为空,如果是我尝试删除它。换句话说,它首先是读取,然后可能是删除,具体取决于目录是否仍然为空。
    • @pjabbott,我想这是一个很好的观点。也许我会只处理异常。无论哪种方式,我都应该这样做......
    【解决方案2】:

    我构建了以下代码。请看看是否有帮助:

    //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();
        }
    }
    

    结果:

    D:\Projects\ConsoleApplication1\bin IdentityReference = BUILTIN\Administrators InheritanceFlags = ContainerInherit, ObjectInherit PropagationFlags = 无 AccessControlType = 允许 FileSystemRights = 完全控制

    注意IdentityReferenceFileSystemRights 属性;可能您应该在尝试删除目录之前针对它们测试您当前的 ACL。

    【讨论】:

    • 我不经常使用 Windows 安全性(好吧,一点也不),所以您能否详细说明我如何检查当前用户(WindowsIdentity.GetCurrent())是否可以从目录?非常感谢您的帮助
    【解决方案3】:

    我相信你需要编写自己的GetDirectories() 方法;递归地获取其中的那些。

    This Microsoft Article 有一篇关于如何做到这一点的好文章,通过一些工作您可以清理它以使用通用列表并使其适合您的解决方案。

    简单地说,System.IO.Directory.GetDirectories() 每次遇到这些异常时都会失败。

    大致像这样的代码(从上面复制)应该可以帮助您入门

        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);
            }
        }
    

    一旦你有了你的目录列表,你就可以对它们执行操作,对于一些模组,上述方法应该确保你对列表中的任何内容都有读取权限。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-25
      • 2020-02-20
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      相关资源
      最近更新 更多