2012-09-11 66 views
3

我正在使用下面的LINQ查詢來獲取目錄列表。我收到一個錯誤(System.UnauthorizedAccessException未被用戶代碼處理)。如何僅加載我有權訪問的目錄。LINQ中的C#句柄System.UnauthorizedAccessException

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

錯誤:

訪問路徑 '\的TestNetwork \ ABC $ \ DemoFolder \' 被拒絕。

+0

我更新了我的答案,正如Wasp所提到的,因爲最後一個答案引發錯誤,請檢查它。 –

回答

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; 
    } 
} 
} 
+0

你確定這個可以工作嗎? 'GetDirectories'作爲一個整體處理文件夾,如果有一個文件夾導致未經授權的訪問,您將無法看到任何輸出,只是例外。至少這就是我看到的測試。 – Wasp

+0

我更新了我的答案@Wasp正如你所提到的,我們需要擴展方法。 –

1

我相信在System.IO命名空間的文件和目錄類中有一些名爲「CanRead」和「CanWrite」的屬性。你可以使用這些來確定你是否有權利。

,我知道的另一種方法是使用代碼訪問安全性,並寫一個方法是「需求」的適當權限....

對不起,我正要進入一個會議,但我已經給了你足夠的谷歌。如果這個問題仍然沒有一個確切的答案,我會寫更多。

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