2012-12-14 153 views
5

更新:我很高興放棄C#的要求,只是看到任何程序,可以列出所有文件作爲管理員或系統運行,我的問題是有人看過這樣的事情?有沒有辦法讓C#中的所有文件名都沒有例外?

有一個目錄中列舉文件的多種方法,但都遭遇了同樣的問題:

「指定的路徑,文件名,或者兩者都太長完全合格的文件名必須小於260字符和目錄名稱必須少於248個字符。「

「訪問路徑‘C:\用戶\所有用戶\應用數據’被拒絕」

即使在管理員,單用戶計算機上運行,​​這似乎是不可能列出所有文件不會遇到例外\錯誤。

是否真的是一個不可能的任務,只是爲了獲得Windows下所有文件的列表?有沒有人能夠使用C#或任何其他方法獲得機器上所有文件的完整列表?

This link from MS標題爲「枚舉目錄和文件」,並沒有說明如何枚舉目錄和文件,這隻能說明什麼,不會拋出一個子集:DirectoryNotFoundException,UnauthorizedAccessException,PathTooLongException,

更新:這裏是通過C運行並嘗試枚舉所有文件和錯誤的示例代碼。即使以admin身份運行,也有不僅可以訪問的文件夾,但我甚至無法將其所有權更改爲Admin!例如:「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

你爲什麼想這樣做? – miniBill

+0

@miniBill:有合法的用例。例如,工作站搜索引擎就像Everything一樣。 –

+1

'DirectoryInfo.GetFiles'是否也會引發異常?如果您的目錄路徑無效,MSDN將僅列出一個'DirectoryNotFoundException'。 http://msdn.microsoft.com/en-us/library/4cyf24ss.aspx。無論如何,編寫實用程序方法來捕獲已知故障應該很簡單。 –

回答

6

是的,這是在非常艱苦至少枚舉所有文件沒有例外。

幾個組的問題在這裏:

  • 一些路(長全1 PathTooLongException)不被CLR支持文件夾/文件重複引進
  • 路口/硬鏈接
  • 安全限制(和在理論上循環以遞歸迭代的方式來處理StackOverflow)。
  • 基本共享衝突限制(如果您嘗試讀取文件)。

對於PathTooLongException:我想你需要處理相應的Win32函數的PInvoke。 CLR中所有與路徑相關的方法限制爲256個字符長。

安全限制 - 如果您在系統(不確定)或具有備份權限的情況下運行,您可能會枚舉所有內容,但其他帳戶無法訪問默認配置的系統上的所有文件。 而不是獲取異常,您可以PInvoke原生版本並處理錯誤代碼。您可以通過直接首先檢查ACL來減少進入目錄的例外數量。

+0

好吧,讓我們忘記CLR吧,你有沒有看到一個使用C,Assmbly或mchine代碼的程序,它可以在任何提升的憑證(如Admin)下運行的單個機器(而不是網絡位置)上實際訪問整個文件系統?無論如何要在自己的機器上獲得所有文件的完整列表? – Arjang

+0

@Arjang我相信大多數文件(全部?),你會得到給予備份特權的帳戶。我從來沒有自己做過,所以沒有我的精確指導。搜索「SE_BACKUP_NAME」,「sebackupprivilege msdn」,並閱讀整體安全性文章(即[使用特權運行](http://msdn.microsoft.com/en-us/library/ms717802(v = vs.85))。 aspx)和[設置備份和恢復權限](http://msdn.microsoft.com/en-us/library/aa387705(VS.85).aspx)。 –

相關問題