2012-12-14 7 views
5
Aggiornamento

: Sono contento di eliminare il requisito C# e di vedere qualsiasi programma in grado di elencare tutti i file in esecuzione come Amministratore o Sistema, la mia domanda è che qualcuno ha visto una cosa del genere?Esiste comunque un modo per ottenere tutti i nomi dei file senza eccezioni in C#?

Ci sono numerosi metodi di enumerazione file in una directory, ma tutti soffrono gli stessi problemi:.

"Il percorso specificato, il nome del file, o entrambi sono troppo lunghi Il nome file completo deve essere inferiore a 260 caratteri e il nome della directory deve essere inferiore a 248 caratteri. "

"Accesso al percorso 'C: \ Users \ All Users \ Application Data' negato"

ecc

Anche in esecuzione sotto admin, macchina di singolo utente, sembra impossibile elencare tutte le file senza incontrare eccezioni \ errori.

È davvero un compito impossibile solo ottenere l'elenco di tutti i file in Windows? Qualcuno è mai stato in grado di ottenere l'elenco completo di tutti i file sul proprio computer utilizzando C# o qualsiasi altro metodo?

This link from MS con il titolo "enumerare directory e file", non mostra come enumerare directory e file, che mostrano solo un sottoinsieme di ciò che non sarà buttare: DirectoryNotFoundException, UnauthorizedAccessException, PathTooLongException,

Aggiornamento: Qui è un codice di esempio da eseguire su C e tenta di enumerare tutti i file e gli errori. Anche quando si esegue questo come amministratore ci sono cartelle che non solo possono essere accessibili, ma nemmeno posso modificare la loro proprietà per l'amministrazione! ad esempio: "C: \ Windows \ CSC"

basta dare un'occhiata al file di registro "Errori {0} .csv" per vedere quanti posti sono inaccessibili da amministrare.

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

Perché vuoi farlo? – miniBill

+0

@miniBill: esistono casi di utilizzo legittimi. Motori di ricerca per workstation, ad esempio, come Tutto. –

+1

Anche 'DirectoryInfo.GetFiles' genera eccezioni? MSDN elenca solo una 'DirectoryNotFoundException' se il percorso della directory non è valido. http://msdn.microsoft.com/en-us/library/4cyf24ss.aspx. Indipendentemente da ciò, dovrebbe essere semplice scrivere un metodo di utilità per individuare i guasti noti. –

risposta

6

Sì, è a meno difficile elencare tutti i file senza eccezioni.

Diversi serie di questioni qui:

  • qualche percorso (lungo PathTooLongException di tipo uno) non sono supportati dal CLR
  • restrizioni di sicurezza su cartelle/file
  • giunzioni/hard link che introducono i duplicati (e in teoria passa a caso StackOverflow in iterazione ricorsiva).
  • restrizioni di violazione di condivisione di base (se si tenta di leggere i file).

Per PathTooLongException: Penso che sarà necessario gestire PInvoke delle funzioni Win32 corrispondenti. Tutti i metodi relativi ai percorsi in CLR sono limitati a 256 caratteri.

Restrizioni di sicurezza: potresti essere in grado di enumerare tutto se esegui il sistema (non sicuro) o con le autorizzazioni di backup, ma qualsiasi altro account è garantito per non poter accedere a tutti i file sul sistema configurato per impostazione predefinita. Invece di ottenere delle eccezioni, è possibile inviare le versioni native di PInvoke e gestire i codici di errore. Potresti essere in grado di ridurre il numero di eccezioni andando nelle directory controllando prima ACL direttamente.

+0

Ok, dimentichiamoci di CLR, hai visto un programma che usa il codice C, Assmbly o mchine che può effettivamente accedere all'intero file system su una singola macchina (non in una rete) con credenziali elevate come Admin? Esiste comunque un elenco completo di tutti i file sulla propria macchina? – Arjang

+0

@Arjang Credo che la maggior parte dei file (tutti?) Si ottenga con l'account che ha dato i privilegi di backup. Non l'ho mai fatto da solo, quindi nessuna guida precisa da parte mia. Cerca "SE_BACKUP_NAME", "sebackupprivilege msdn" e leggi gli articoli complessivi relativi ai documenti protetti (ad esempio [Esecuzione con privilegi speciali] (http://msdn.microsoft.com/en-us/library/ms717802 (v = vs.85). aspx) e [Impostazione dei privilegi di backup e ripristino] (http://msdn.microsoft.com/en-us/library/aa387705 (VS.85) .aspx) che provengono da ricerche precedenti). –

Problemi correlati