[英]How to access files inside "System Volume Information" Directory
I'm trying to get list of all files inside a folder (or drive).我正在尝试获取文件夹(或驱动器)中所有文件的列表。
Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
throws an error because access to some directories like System Volume Information is denied.引发错误,因为对某些目录(如System Volume Information )的访问被拒绝。 all answer about this are suggesting catching the error and bypassing these directories while my main purpose is bypassing other directories and read these special directories.关于此的所有答案都建议捕获错误并绕过这些目录,而我的主要目的是绕过其他目录并读取这些特殊目录。
I know that I can grant access and then revoke the access like:我知道我可以授予访问权限,然后撤销访问权限,例如:
icacls "C:\System Volume Information" /grant username:F
and和
icacls "C:\system volume information" /remove username
but it does not seem like a wise choice just to run 2 process (one for granting and one for revoking) access to each directory with System.UnauthorizedAccessException
.但仅使用System.UnauthorizedAccessException
运行 2 个进程(一个用于授予,一个用于撤销)对每个目录的访问似乎并不是一个明智的选择。
is there a better way to grant access to such directories programmatically?有没有更好的方法以编程方式授予对此类目录的访问权限?
I don't think it's a good idea to grant access to users for system folders in general.我认为授予用户访问系统文件夹的权限一般不是一个好主意。 Your approach is to search for any folder under C:.您的方法是搜索 C: 下的任何文件夹。 This creates all kind of problems, since MS creates folders there with only SYSTEM access.这会产生各种问题,因为 MS 在那里创建了只有系统访问权限的文件夹。 If you really want access to everything, I would suggest that you run your app as SYSTEM.如果您真的想访问所有内容,我建议您以 SYSTEM 身份运行您的应用程序。 Otherwise, filter out the folders you really need access to, and only try to access them.否则,过滤掉您真正需要访问的文件夹,并且只尝试访问它们。 There is multiple solutions out there on how to run your program as the SYSTEM user.关于如何以 SYSTEM 用户身份运行程序,有多种解决方案。 One of them (which I casually use when testing) is PSTools.其中之一(我在测试时随意使用)是 PSTools。
https://docs.microsoft.com/en-us/sysinternals/downloads/pstools https://docs.microsoft.com/en-us/sysinternals/downloads/pstools
As mention grant access to folder is even temporarily not a good idea.如前所述,授予对文件夹的访问权限甚至暂时不是一个好主意。 But if you really need that temporarily access only for enumeration files you can modify ACL to grant current user right to read folder only (Enumerate file) and restore it back after enumeration in C# without call additional utilities.但是,如果您确实需要仅对枚举文件进行临时访问,您可以修改 ACL 以授予当前用户仅读取文件夹(枚举文件)的权限,并在 C# 中枚举后将其恢复,而无需调用其他实用程序。
Code above above can do such enumeration that way.上面的代码可以通过这种方式进行枚举。 Beware ever admin account in some folder don't have access to modify or read ACL.请注意某些文件夹中的管理员帐户无权修改或读取 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.