5

更新:C#要件を削除して、管理者またはシステムとして実行されているすべてのファイルを一覧表示できるプログラムを確認できてうれしいです。私の質問は、誰かがそのようなことを見たことがありますか?

ディレクトリ内のファイルを列挙する方法は多数ありますが、すべて同じ問題が発生します。

「指定されたパス、ファイル名、またはその両方が長すぎます。完全修飾ファイル名は260文字未満である必要があり、ディレクトリ名は248文字未満である必要があります。」

「パス'C:\ Users \ All Users \ApplicationData'へのアクセスが拒否されました」

admin、シングルユーザーマシンで実行している場合でも、exceptions\errorsが発生しない限りすべてのファイルを一覧表示することは不可能のようです。

ウィンドウの下にあるすべてのファイルのリストを取得するだけでは本当に不可能な作業ですか?誰かがC#または他の方法を使用して自分のマシン上のすべてのファイルの完全なリストを取得できたことがありますか?

「ディレクトリとファイルを列挙する」というタイトルの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);
    }

    }
}
4

1 に答える 1

6

はい、少なくとも例外なくすべてのファイルを列挙することは困難です。

ここにいくつかの問題があります:

  • 一部のパス(長いパス-PathTooLongException)はCLRでサポートされていません
  • フォルダ/ファイルのセキュリティ制限
  • 重複を導入するジャンクション/ハードリンク(および理論的には、再帰的な反復でStackOverflowの場合に循環します)。
  • 基本的な共有違反の制限(ファイルを読み取ろうとした場合)。

PathTooLongExceptionの場合:対応するWin32関数のPInvokeを処理する必要があると思います。CLRのすべてのパス関連メソッドは、256文字の長さに制限されています。

セキュリティの制限-システム(わからない)またはバックアップ権限で実行している場合はすべてを列挙できる可能性がありますが、他のアカウントはデフォルトで構成されているシステム上のすべてのファイルにアクセスできないことが保証されています。例外を取得する代わりに、ネイティブバージョンをPInvokeして、代わりにエラーコードを処理できます。最初に直接ACLをチェックすることで、ディレクトリに入る際の例外の数を減らすことができる場合があります。

于 2012-12-14T21:22:21.860 に答える