![](/img/trans.png)
[英]C# - Exclude directories and files from Directory.GetDirectories() and Directory.GetFiles()
[英]In C# .NET, what directories can Directory.GetDirectories or Directory.GetFiles not get directories or files from, and Why?
在 C# .NET 中,某些传递给Directory.GetDirectories
或Directory.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.