繁体   English   中英

在 C# .NET 中,Directory.GetDirectories 或 Directory.GetFiles 无法从哪些目录中获取目录或文件,为什么?

[英]In C# .NET, what directories can Directory.GetDirectories or Directory.GetFiles not get directories or files from, and Why?

在 C# .NET 中,某些传递给Directory.GetDirectoriesDirectory.GetFiles的目录抛出异常。 那些导致它无法读取的目录到底是什么?

simpletest1_test_exceptions_with_those_functions(@"C:\");
simpletest1_test_exceptions_with_those_functions(@"C:\windows");

以下 function (simpletest1_test_exceptions_with_those_functions) 我写来测试 GetDirectories 和 GetFiles,工作正常,它显示无法访问哪些目录,但问题是为什么。

请注意,function 有意注释掉了很多内容,因为它有能力递归浏览整个目录树,但我已经注释掉了它,因此它只执行目录树的一个级别。 它通常会列出所有文件和目录,但我已经评论过了。 这样当它无法访问的目录作为参数传递时,它只显示 GetDirectories function 无法访问的目录。

static void simpletest1_test_exceptions_with_those_functions(string sDir)
{
    // can't just have a try catch at the end otherwise it won't return.

    try 
    {

        Console.WriteLine("DirSearch..(" + sDir + ")");

        //Console.WriteLine(sDir);

        Console.WriteLine("files");
        foreach (string f in Directory.GetFiles(sDir))
        {
            // Console.WriteLine(f);
        }

        Console.WriteLine("directories");
        foreach (string d in Directory.GetDirectories(sDir))
        {
            // testexceptionwiththosefunctions(d);
            // Console.WriteLine(d);

            try
            {
                foreach (string f in Directory.GetFiles(d))
                {
                    // Console.WriteLine(f);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("z Directory.GetFiles threw exception");
                Console.WriteLine(e.Message);
            }
        }
    
    }
    catch(Exception ee)
    {
        Console.WriteLine("some exception thrown");
    }
  
    
}

DirSearch..(C:\)
files
directories
z Directory.GetFiles threw exception
Access to the path 'C:\Documents and Settings' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\MSOCache' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\Recovery' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\System Volume Information' is denied.
-----
DirSearch..(C:\windows)
files
directories
z Directory.GetFiles threw exception
Access to the path 'C:\windows\LiveKernelReports' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\windows\Minidump' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\windows\ModemLogs' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\windows\Prefetch' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\windows\Temp' is denied.

在这些路径之外..“文档和设置”是一个路口,很好,无法处理通过路口的问题。

(dir /a 显示所有目录,无论是隐藏的还是系统的还是只读的,只是全部)

C:\>dir /a | find "Docu"
14/07/2009  06:08    <JUNCTION>     Documents and Settings [C:\Users]

C:\>

但是,列出的所有其他目录都没有交叉点。

所以并不是说它不能在路口上工作。

另外,我可以 CD 进入 Documents and Settings,我不能进入许多其他目录。 我可以 CD 进入C:\Windows\temp虽然其他人我不能

C:\Windows>cd Temp

C:\Windows\Temp>cd ..

C:\Windows>cd LiveKernelReports
Access is denied.

C:\Windows>

无论是隐藏的还是系统的还是只读的都不相关

例如这个目录不是隐藏的或系统的或只读的

C:\Windows>dir | find "Live"
14/07/2009  03:34    <DIR>          LiveKernelReports

C:\Windows>attrib LiveKernelReports
             C:\Windows\LiveKernelReports

C:\Windows>

这不是系统或隐藏的问题,因为 Directory.GetFiles 和 Directory.GetDirectories 在此类目录上没有问题。 我尝试创建 c:\atest\hdir(其中 hdir 是隐藏目录)和 c:\test\sdir(其中 sdir 是系统目录)

C:\atest>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\atest

17/07/2020  02:45    <DIR>          .
17/07/2020  02:45    <DIR>          ..
17/07/2020  02:44    <DIR>          hdir
17/07/2020  02:45    <DIR>          rdir
17/07/2020  02:44    <DIR>          sdir
               0 File(s)              0 bytes
               5 Dir(s)  286,734,127,104 bytes free

C:\atest>attrib +h hdir

C:\atest>attrib +r rdir

C:\atest>attrib +s sdir

C:\atest>attrib sdir
   S         C:\atest\sdir

C:\atest>attrib hdir
    H        C:\atest\hdir

C:\atest>attrib rdir
     R       C:\atest\rdir

C:\atest>

我使用这个更简单的 function 来验证特定路径(传递给 GetFiles 或 GetDirectories)是否抛出异常以及我创建的隐藏/系统/只读目录不会抛出异常。

它验证了系统/只读/隐藏与它无关。

static void test_exception_with_thosefunctions()
{
    string[] dirs=null;
    string[] files=null;
    string dirstr="";
    try
    {
        // dirs = Directory.GetDirectories(@"C:\Documents and Settings");
        dirstr = @"c:\atest\hdir";
        dirs = Directory.GetDirectories(dirstr);
        files = Directory.GetFiles(dirstr);

        dirstr = @"c:\atest\rdir";
        dirs = Directory.GetDirectories(dirstr);
        files = Directory.GetFiles(dirstr);

        dirstr = @"c:\atest\sdir";
        dirs = Directory.GetDirectories(dirstr);
        files = Directory.GetFiles(dirstr);

        // files = Directory.GetFiles(@"C:\Documents and Settings");
        Console.WriteLine(dirs.Length);
    }
    catch(Exception e)
    {
        //if(dirs!=null) Console.WriteLine(dirs.Length);
        //if(files!=null) Console.WriteLine(files.Length);
        Console.WriteLine(e.Message);
    }
}

所以我列出的那些路径显然有一些东西会抛出异常..我想知道它们是什么?

简单地说,您没有访问这些目录的权限。

以管理员身份运行(提升)您的应用程序/命令提示符将解决很多问题。

我将接受 TheGeneral 的回答,它涵盖了我提到的大部分目录,但不包括这两个目录 - “文档和设置”和“系统卷信息”。

我发布了这个答案以涵盖 Eryk Sun 在评论中提到的内容,其中涵盖了这两个目录。

将军关于从管理 cmd 提示运行的回答“因为有些需要管理权限,当然可以回答其中的许多情况,尽管不是全部

C:\blah>ConsoleApp1.exe
adf
0
DirSearch..(C:\)
files
directories
z Directory.GetFiles threw exception
Access to the path 'C:\Documents and Settings' is denied.
z Directory.GetFiles threw exception
Access to the path 'C:\System Volume Information' is denied.
-----
DirSearch..(C:\windows)
files
directories

因此,即使在管理 cmd 提示符下,也显示两个目录仍未被读取。

C:\Documents and Settings目录和“C:\System Volume Information”目录。

Eryk Sun 提到“为了兼容挂载点(又名连接点),每个人 (S-1-1-0) 都被拒绝列出目录的权利。它们的存在只是为了访问子目录(例如目录“C:\Documents and Settings \Public")。这与它们是挂载点这一事实毫无关系。它只是目录上设置的自由访问控制列表的 function。

Eryk 提到“ icacls “C:\Documents and Settings” 应该对每个人都有一个拒绝条目 (S-1-1-0),但是该组的友好名称已本地化(检查 sysinternals psgetsid s-1-1-0) . 大多数文件夹不会向所有人授予访问权限。通常,它们向“经过身份验证的用户”(S-1-5-11)、系统 (S-1-5-18)、管理员 (S-1-5) 等组授予访问权限-32-544)和用户(S-1-5-32-545)”

事实上 icacls "C:\Documents and Settings" 确实显示了每个人的拒绝条目

C:\Windows\system32>icacls "C:\Documents and Settings"
C:\Documents and Settings Everyone:(DENY)(S,RD)
                          Everyone:(RX)
                          NT AUTHORITY\SYSTEM:(F)
                          BUILTIN\Administrators:(F)

Successfully processed 1 files; Failed processing 0 files

所以留下C:\System Volume Information作为剩下的谜团。

Eryk 提到“通常不会授予任何访问权限,除非它是由自由访问控制列表 (DACL) 中的条目特别授予的。在“C:\System Volume Information”的情况下,只有 SYSTEM 组 (S-1-5-18)被授予访问权限。通常只有系统服务在 SYSTEM 进程中运行。您可以通过 sysinternals psexec 以 SYSTEM 身份运行,例如 psexec -sid cmd.exe 并在打开的命令提示符中检查 whoami。

和 Eryk 提到“DACL 规则有一些常见的例外情况。object 的所有者被隐式授予 READ_CONTROL 和 WRITE_DAC 访问权限,以便能够读取和修改 DACL,并且所有用户都拥有的 SeChangeNotifyPrivilege 允许遍历目录到它的即使没有授予目录访问权限的孩子”

事实上,如果我运行该 psexec 命令psexec -sid cmd.exe以便以系统用户身份运行 cmd.exe,那么我可以进入并列出系统卷信息目录。 而whoami显示是系统用户。

C:\Windows\system32>cd "\System Volume Information"

C:\System Volume Information>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\System Volume Information

26/12/2019  11:39        50,790,280 smartdb_Volume{f0f46b52-75c5-11e6-87ea-806e6
f6e6963}.sdb
18/07/2020  19:21         2,621,440 Syscache.hve
24/04/2020  02:39    <DIR>          Windows Backup
24/04/2020  16:06    <DIR>          WindowsImageBackup
               2 File(s)     53,411,720 bytes
               2 Dir(s)  289,325,735,936 bytes free

C:\System Volume Information>whoami
nt authority\system

C:\System Volume Information>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM