【问题标题】:Read folder as admin in c#在 C# 中以管理员身份读取文件夹
【发布时间】:2020-06-12 19:54:12
【问题描述】:

我正在尝试使用以下方式在“C:\”文件夹中查找文件:

var allFiles = Directory.GetFiles("C:\\", "VBoxManage.exe", SearchOption.AllDirectories);

如果我不尝试读取需要管理员权限的目录,则代码可以正常工作。 我在我的 app.manifest 中添加了这一行:

 <requestedExecutionLevel level="highestAvailable" uiAccess="false" />

应用程序在运行时要求管理员权限,但仍然给出如下错误:

System.UnauthorizedAccessException: 'Permission to 'C:\Documents and Settings' denied.'

有什么建议吗?

【问题讨论】:

  • 编写 C# 代码和/或以管理员身份运行并不意味着管理员帐户会神奇地获得管理员自然也没有权限的地方的权限...
  • 在当前的 Windows 中,“文档和设置”是“用户”的连接点,可能会导致问题。如果您尝试“以管理员身份”运行程序会发生什么?
  • stackoverflow.com/questions/10963888/… 表示这个问题与那个文件夹有关,正如 NetMage 所说,这是一个连接点。
  • 附带说明,扫描整个 C 驱动器以查找特定的可执行文件通常是个坏主意。查看VBoxManage.exe 是否以某种方式在注册表中或PATH 下列出了自己。
  • C:\Documents and Settings 甚至管理员都无法访问。它只是C:\Users 的别名。

标签: c# .net windows admin


【解决方案1】:

我编写了这些扩展方法来处理跳过不可访问的文件和文件夹:

#region SafeWalk
public static class SafeWalk {
    [Flags]
    public enum ReturnOptions {
        ReturnFiles = 1, ReturnDirectories = 2, ReturnBoth = 3
    }

    const string AllFiles = "*.*";

#region File and Directory Names
    // File and Directory Name Tree Walkers
#region File and Dir Names
    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.FullName.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.FullName.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnBoth);

    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnBoth);

    public static IEnumerable<string> SafeEnumerateFileAndDirNames(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) {
        var searchQueue = new Queue<string>() { path };

        while (searchQueue.Count > 0) {
            var cdn = searchQueue.Dequeue();

            IEnumerable<string> cdiFiles = null;
            if (returnOpt.HasFlag(ReturnOptions.ReturnFiles)) {
                try {
                    cdiFiles = Directory.EnumerateFiles(cdn, filePattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiFiles != null)
                    foreach (var filename in cdiFiles)
                        yield return filename;
            }

            if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt.HasFlag(SearchOption.AllDirectories))) { // skip if file enumeration failed
                IEnumerable<string> cdiDirs = null;
                try {
                    cdiDirs = Directory.EnumerateDirectories(cdn, dirPattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiDirs != null) {
                    foreach (var dirname in cdiDirs) {
                        if (searchOpt == SearchOption.AllDirectories)
                            searchQueue.Enqueue(dirname);

                        if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
                            yield return dirname;
                    }
                }
            }
        }
    }
#endregion
#region File Names
    public static IEnumerable<string> SafeEnumerateFileNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

    public static IEnumerable<string> SafeEnumerateFileNames(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

    public static IEnumerable<string> SafeEnumerateFileNames(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles);

    public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

    public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.FullName.SafeEnumerateFileAndDirNames(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles);

    public static IEnumerable<string> SafeEnumerateFileNames(this DirectoryInfo path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.FullName.SafeEnumerateFileAndDirNames(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles);
#endregion
#region Dir Names
    public static IEnumerable<string> SafeEnumerateDirectoryNames(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories);

    public static IEnumerable<string> SafeEnumerateDirectoryNames(this string path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.SafeEnumerateFileAndDirNames(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories);

    public static IEnumerable<string> SafeEnumerateDirectoryNames(this DirectoryInfo path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.FullName.SafeEnumerateFileAndDirNames(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories);

    public static IEnumerable<string> SafeEnumerateDirectoryNames(this DirectoryInfo path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        path.FullName.SafeEnumerateFileAndDirNames(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories);
#endregion
#endregion

#region File and Directory Infos
    // File and Directory Info Tree Walkers
#region File System Infos
    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, returnOpt);

    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, string searchPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(searchPattern, searchPattern, searchOpt, returnOpt);

    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, returnOpt);

    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
        di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, returnOpt);

    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string searchPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) =>
        di.SafeEnumerateFileSystemInfos(searchPattern, searchPattern, searchOpt, returnOpt);

    public static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) {
        var searchQueue = new Queue<DirectoryInfo>();
        searchQueue.Enqueue(di);
        while (searchQueue.Count > 0) {
            var cdi = searchQueue.Dequeue();

            IEnumerable<string> cdiFiles = null;
            if (returnOpt.HasFlag(ReturnOptions.ReturnFiles)) {
                try {
                    cdiFiles = Directory.EnumerateFiles(cdi.FullName, filePattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiFiles != null) {
                    var cfis = new ConcurrentBag<FileInfo>();
                    cdiFiles.AsParallel()
                            .ForAll(f => {
                                try {
                                    cfis.Add(new FileInfo(f));
                                }
                                catch (Exception) {
                                }
                            });

                    foreach (var fi in cfis)
                        yield return fi;
                }
            }

            if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt.HasFlag(SearchOption.AllDirectories))) { // skip if file enumeration failed
                IEnumerable<string> cdiDirs = null;
                try {
                    cdiDirs = Directory.EnumerateDirectories(cdi.FullName, dirPattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiDirs != null) {
                    var cdis = new ConcurrentBag<DirectoryInfo>();
                    cdiDirs.AsParallel()
                           .ForAll(d => {
                               try {
                                   cdis.Add(new DirectoryInfo(d));
                               }
                               catch (Exception) {
                               }
                           });
                    foreach (var rdi in cdis) {
                        if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
                            yield return rdi;
                        if (searchOpt == SearchOption.AllDirectories)
                            searchQueue.Enqueue(rdi);
                    }
                }
            }
        }
    }
#endregion
#region File Infos
    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, string filePattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.SafeEnumerateFileSystemInfos(filePattern, AllFiles, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();

    public static IEnumerable<FileInfo> SafeEnumerateFileInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.SafeEnumerateFileSystemInfos(filePattern, dirPattern, searchOpt, ReturnOptions.ReturnFiles).Cast<FileInfo>();
#endregion
#region Directory Infos
    public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this string path, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

    public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this string path, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        new DirectoryInfo(path).SafeEnumerateFileSystemInfos(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

    public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this DirectoryInfo di, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.SafeEnumerateFileSystemInfos(AllFiles, AllFiles, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();

    public static IEnumerable<DirectoryInfo> SafeEnumerateDirectoryInfos(this DirectoryInfo di, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly) =>
        di.SafeEnumerateFileSystemInfos(AllFiles, dirPattern, searchOpt, ReturnOptions.ReturnDirectories).Cast<DirectoryInfo>();
#endregion
#endregion
}
#endregion

定义了这些之后,您可以:

var ans = @"C:\".SafeEnumerateFileNames("VBoxManage.exe", SearchOption.AllDirectories);

【讨论】:

    猜你喜欢
    • 2013-09-23
    • 2011-04-05
    • 2014-01-28
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多