簡體   English   中英

在LINQ中C#處理System.UnauthorizedAccessException

[英]C# Handle System.UnauthorizedAccessException in LINQ

我在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 \\'被拒絕。

我不明白你為什么需要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
    }
}

您應該做的第一件事是更改您正在使用的方法:

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

EnumerateDirectories工作得更好,因為它產生結果,並且如果它找到一個沒有rigths的文件夾,仍會拋出相同的異常。 它產生結果的事實允許我們在其輸出之上進行組合,因此如果我們添加如下的擴展方法:

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方法的想法是“吞下”你不想要的異常,而不會阻止其他異常發生。 這是一個草案實施,但你明白了。

我相信在System.IO命名空間的File和Directory類中有一些名為“CanRead”和“CanWrite”的屬性。 您可以使用它們來確定您是否擁有權利。

我所知道的另一種方法是使用代碼訪問安全性並編寫一個“需要”相應權限的方法....

對不起,我正准備參加一個會議,但我已經給了你足夠的谷歌了。 如果這個問題仍然沒有一個可靠的答案,我會稍后再寫。

使用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;
    }
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM