3

以下のLINQクエリを使用してディレクトリリストを取得しています。エラーが発生します(System.UnauthorizedAccessExceptionがユーザーコードによって処理されませんでした)。アクセスできるディレクトリのみをロードする方法。

var files = from f in System.IO.Directory.GetDirectories(@"\\testnetwork\abc$",
                                   "*.*",
                                   SearchOption.AllDirectories)
            select System.IO.Path.GetDirectoryName(f);

エラー:

パス'\testnetwork \ abc $ \DemoFolder\'へのアクセスは拒否されます。

4

4 に答える 4

2

最初にすべきことは、使用している方法を変更することです。

var files = from f in System.IO.Directory.EnumerateDirectories(
        @"\\testnetwork\abc$",
        "*.*",
        SearchOption.AllDirectories)
select f;

EnumerateDirectories結果が得られるため、より適切に機能しますが、リグがないフォルダーが見つかった場合でも同じ例外がスローされます。結果が得られるという事実により、出力の上に作成することができます。したがって、次のような拡張メソッドを追加すると、次のようになります。

static class ExceptionExtensions
{
    public static IEnumerable<TIn> Catch<TIn>(
                this IEnumerable<TIn> source,
                Type exceptionType)
    {   
        using (var e = source.GetEnumerator())
        while (true)
        {
            var ok = false;

            try
            {
                ok = e.MoveNext();
            }
            catch(Exception ex)
            {
                if (ex.GetType() != exceptionType)
                    throw;
                continue;
            }

            if (!ok)
                yield break;

            yield return e.Current;
        }
    }
}

次に、次のようなものを書くことができます。

var files = from f in System.IO.Directory.EnumerateDirectories(
        @"\\testnetwork\abc$",
        "*.*",
        SearchOption.AllDirectories)
        .Catch(typeof(UnauthorizedAccessException))
select f;

また、Linq式をクリーンで構成可能な状態に保ちながら、出力は期待どおりの出力になるはずです。この方法の考え方はCatch、他の例外が発生するのを防ぐことなく、不要な例外を「飲み込む」ことです。これはドラフト実装ですが、あなたはその考えを理解します。

于 2012-09-11T18:20:39.177 に答える
2

このためにLINQが必要な理由がわかりません。シンプルに保つと、問題のデバッグに役立つ場合があります。次のようなものを試してください。

DirectoryInfo[] directories = System.IO.Directory.GetDirectories(@"\\testnetwork\abc$",
                               "*.*",
                               SearchOption.AllDirectories);
foreach (DirectoryInfo dir in directories)
{
    try
    {
       Console.WriteLine(System.IO.Path.GetDirectoryName(f));
    }
    catch(Exception ex)
    {
       // report an error or something
    }
}
于 2012-09-11T15:56:20.813 に答える
1

Catchを使用してUnauthorizedAccessExceptionをキャッチします。。

  string[] directories = Directory.EnumerateDirectories(@"\\testnetwork\abc$","*.*", SearchOption.AllDirectories).Catch(typeof(UnauthorizedAccessException)).ToArray();

ExceptionExtensions:

   static class ExceptionExtensions
{
public static IEnumerable<TIn> Catch<TIn>(
            this IEnumerable<TIn> source,
            Type exceptionType)
{   
    using (var e = source.GetEnumerator())
    while (true)
    {
        var ok = false;

        try
        {
            ok = e.MoveNext();
        }
        catch(Exception ex)
        {
            if (ex.GetType() != exceptionType)
                throw;
            continue;
        }

        if (!ok)
            yield break;

        yield return e.Current;
    }
}
}
于 2012-09-11T16:00:50.980 に答える
1

System.IO名前空間のFileクラスとDirectoryクラスには「CanRead」と「CanWrite」というプロパティがあると思います。それらを使用して、自分が権利を持っているかどうかを判断できます。

私が知っているもう1つの方法は、Code Access Securityを使用して、適切な特権を「要求する」メソッドを作成することです。

申し訳ありませんが、会議に参加しようとしていますが、Googleに十分な情報を提供しました。この質問にまだ確かな答えがない場合は、後で詳しく説明します。

于 2012-09-11T15:55:12.927 に答える