更新:我很高兴放弃C#的要求,只看到任何可以列出作为管理员或系统运行的文件的程序,我的问题是有人见过这样的事情吗?
在目录中有许多枚举文件的方法,但都遇到了同样的问题:
“指定的路径,文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名称必须少于248个字符。”
“访问路径'C:\ Users \ All Users \ Application Data'被拒绝”
等
即使在管理员,单用户计算机下运行,似乎也无法列出所有文件而不会遇到异常\错误。
获取windows下所有文件的列表真的是一项不可能完成的任务吗?有没有人能够使用C#或任何其他方法获取其机器上所有文件的完整列表?
标题为“Enumerate Directories and Files”的This link from MS没有显示如何枚举目录和文件,它只显示了不会抛出的内容的一部分:DirectoryNotFoundException,UnauthorizedAccessException,PathTooLongException,
更新:以下是在C上运行的示例代码,并尝试枚举所有文件和错误。即使以管理员身份运行此文件,也有不仅可以访问的文件夹,但我甚至无法将其所有权更改为管理员!例如:“C:\ Windows \ CSC”
只需查看“错误{0} .csv”日志文件,即可查看管理员无法访问的地点数。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Program
{
static System.IO.StreamWriter logfile;
static System.IO.StreamWriter errorfile;
static void Main(string[] args)
{
string directory = @"C:\";
logfile = new System.IO.StreamWriter(string.Format(@"E:\Files {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
errorfile = new System.IO.StreamWriter(string.Format(@"E:\Errors {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
TraverseTree(directory, OnGotFileInfo, OnGotException);
logfile.Close();
errorfile.Close();
}
public static void OnGotFileInfo(System.IO.FileInfo fileInfo)
{
logfile.WriteLine("{0},{1},", fileInfo.FullName, fileInfo.Length.ToString("N0"));
}
public static void OnGotException(Exception ex, string info)
{
errorfile.WriteLine("{0},{1}", ex.Message, info);
}
public static void TraverseTree(string root, Action<System.IO.FileInfo> fileAction, Action<Exception, string> errorAction)
{
// Data structure to hold names of subfolders to be
// examined for files.
Stack<string> dirs = new Stack<string>(20);
if (!System.IO.Directory.Exists(root))
{
throw new ArgumentException();
}
dirs.Push(root);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (System.Exception e)
{
errorAction(e, currentDir);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (System.Exception e)
{
errorAction(e, currentDir);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
fileAction(fi);
}
catch (System.Exception e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
errorAction(e ,file);
continue;
}
}
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
}
答案 0 :(得分:6)
是的,至少很难枚举所有文件而没有例外。
这里有几个问题:
对于PathTooLongException:我认为你需要处理相应Win32函数的PInvoke。 CLR中所有与路径相关的方法都限制为256个字符。
安全限制 - 如果您在系统(不确定)下运行或具有备份权限,您可能能够枚举所有内容,但保证任何其他帐户无法访问默认配置的系统上的所有文件。 您可以PInvoke本机版本并处理错误代码,而不是获得异常。您可以通过直接检查ACL来减少进入目录的异常数量。