![](/img/trans.png)
[英]Access Denied on accessing the system folder of any drive like system volume information
[英]How to access files inside "System Volume Information" Directory
我正在尝试获取文件夹(或驱动器)中所有文件的列表。
Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
引发错误,因为对某些目录(如System Volume Information )的访问被拒绝。 关于此的所有答案都建议捕获错误并绕过这些目录,而我的主要目的是绕过其他目录并读取这些特殊目录。
我知道我可以授予访问权限,然后撤销访问权限,例如:
icacls "C:\System Volume Information" /grant username:F
和
icacls "C:\system volume information" /remove username
但仅使用System.UnauthorizedAccessException
运行 2 个进程(一个用于授予,一个用于撤销)对每个目录的访问似乎并不是一个明智的选择。
有没有更好的方法以编程方式授予对此类目录的访问权限?
我认为授予用户访问系统文件夹的权限一般不是一个好主意。 您的方法是搜索 C: 下的任何文件夹。 这会产生各种问题,因为 MS 在那里创建了只有系统访问权限的文件夹。 如果您真的想访问所有内容,我建议您以 SYSTEM 身份运行您的应用程序。 否则,过滤掉您真正需要访问的文件夹,并且只尝试访问它们。 关于如何以 SYSTEM 用户身份运行程序,有多种解决方案。 其中之一(我在测试时随意使用)是 PSTools。
https://docs.microsoft.com/en-us/sysinternals/downloads/pstools
如前所述,授予对文件夹的访问权限甚至暂时不是一个好主意。 但是,如果您确实需要仅对枚举文件进行临时访问,您可以修改 ACL 以授予当前用户仅读取文件夹(枚举文件)的权限,并在 C# 中枚举后将其恢复,而无需调用其他实用程序。
上面的代码可以通过这种方式进行枚举。 请注意某些文件夹中的管理员帐户无权修改或读取 ACL。
public static IReadOnlyList<string> EnumerateFile(
string path,
bool recursive = false,
bool ignoreError = true)
{
var currentIdentity = WindowsIdentity.GetCurrent();
List<string> result;
try
{
result = Directory.EnumerateFiles(path).ToList();
if (recursive)
{
foreach(var dir in Directory.EnumerateDirectories(path))
{
var r = EnumerateFile(dir, true);
result.AddRange(r);
}
}
return result;
}
catch(UnauthorizedAccessException)
{
try
{
var accessControl = Directory.GetAccessControl(path);
accessControl.ModifyAccessRule(
AccessControlModification.Add,
new FileSystemAccessRule(
currentIdentity.User,
FileSystemRights.ListDirectory,
AccessControlType.Allow),
out var success);
if (!success)
throw new UnauthorizedAccessException();
Directory.SetAccessControl(path, accessControl);
result = Directory.EnumerateFiles(path).ToList();
if (recursive)
{
foreach (var dir in Directory.EnumerateDirectories(path))
{
var r = EnumerateFile(dir, true);
result.AddRange(r);
}
}
accessControl.ModifyAccessRule(
AccessControlModification.Remove,
new FileSystemAccessRule(
currentIdentity.User,
FileSystemRights.ListDirectory,
AccessControlType.Allow),
out _);
Directory.SetAccessControl(path, accessControl);
return result;
}
catch (UnauthorizedAccessException e)
{
return ignoreError ? new List<string>() : throw e;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.