繁体   English   中英

如何访问“系统卷信息”目录中的文件

[英]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.

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