C#:如何检查我是否可以读取和/或删除目录

发布于 2024-08-08 17:30:20 字数 259 浏览 7 评论 0原文

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

所以,当我有一个 DirectoryInfo 对象时。如何查看是否允许 GetDirectories() 以及可能的 Delete() 操作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱格式化 2024-08-15 17:30:20

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

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

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.

抽个烟儿 2024-08-15 17:30:20

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

//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  = None
    AccessControlType = Allow
    FileSystemRights  = FullControl

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

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.

不知所踪 2024-08-15 17:30:20

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

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

简而言之,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);
        }
    }

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文