2012-10-28 61 views
2

我的應用程序使用.NET對象的所有文件Directory.GetFiles()C# - 無法訪問

我使用的實際過載

var allFiles = Directory.GetFiles("C:\\Users\\Dave", "*.*", SearchOption.AllDirectories); 

的問題是當源文件夾是C:\ Users \用戶名因爲它然後嘗試查看應用程序數據文件夾。

當試圖從應用程序數據文件夾來讀取,則拋出異常:

「訪問路徑‘C:\用戶\戴夫\應用程序數據\本地\應用 數據’被拒絕。 「

所以,我的問題是否有任何人對我的選擇有意見?我假設我必須改變我收集所有文件的方式,或者可能有內置的重載或方法,這將允許我繼續這個(我明顯不知道的)。

如果有幫助,其目標是獲取Directory.GetFiles()檢索的所有文件,並將其粘貼到其他位置(一個優化的副本並粘貼/備份)。我其實並不太擔心繫統文件,只是'用戶文件'。

+0

您的程序在哪個帳戶下運行? – mbarthelemy

+0

好問題 - 目前,這在我的家用電腦上 - 這是我的帳戶,我是管理員的完整權利。雖然我不知道我的程序是否像完全權限一樣運行,因爲我在調試模式下運行VS(準確地說,使用MS TESTS) – Dave

+0

如果以管理員身份運行Visual Studio(右鍵單擊>以管理員身份運行)這行得通? –

回答

3

目錄%AppData%是受系統保護的目錄。只要訪問權限未被授權(來自管理員以外的其他用戶的訪問權限),Windows將嘗試阻止對此目錄的任何訪問。

只有管理員在默認情況下具有讀寫該目錄的權限。

或者,您可以捕獲異常並查看結果是否爲Access Denied。然後,您可以提示用戶以管理員身份運行以完成此步驟。這裏有一個簡單的例子來提示用戶以管理員身份運行

try 
{ 
    var allFiles = Directory.GetFiles("C:\\Users\\Dave", "*.*", SearchOption.AllDirectories); 
} 
catch (Exception EX) 
{ 
    if (EX.Message.ToLower().Contains("is denied.")) 
    { 
      ProcessStartInfo proc = new ProcessStartInfo(); 
      proc.UseShellExecute = true; 
      proc.WorkingDirectory = Environment.CurrentDirectory; 
      proc.FileName = Application.ExecutablePath; 
      proc.Verb = "runas"; //Required to run as Administrator 
      try 
      { 

      Process.Start(proc); 

      } 
      catch 
      { 
       //The user refused to authorize 
      } 
    } 
} 

然而,你可能總是提示用戶授權時,應用程序啓動時它並不總是建議。要做到這一點,你必須編輯您的項目app.manifest文件

找到並更改以下行

<requestedExecutionLevel level="asInvoker" uiAccess="false" /> 

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 

謝謝,
我希望你能找到這個有幫助:)

+0

好的,這是我猜測的,但無法確定,所以謝謝你,這是非常好的細節。我想知道,如果通過使用Environment.GetSpeicalFolder()方法查看文件路徑是否與%appdata%文件夾相匹配,並且它匹配,可以跳過它,因爲我不想在可能的情況下依賴捕獲。 +1 – Dave

+0

@DaveRook你也可以使用它! 'Environment.ExpandEnvironmentVariables(「%AppData%」);'但我並不認爲這是一個很好的編程習慣。您始終可以提示用戶進行授權,如果他拒絕,則可以跳過處理該文件夾。有一個偉大的一天:) –

+1

對不起,我的意思是使用如果(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).Contains(sourceFolder))..但是,我明白可能有不少我必須設置爲:S – Dave

1

最好使用一個foreach循環來獲取您可以訪問的文件夾名稱:

DirectoryInfo dI = new DirectoryInfo(@"C:\Users\Dave"); 
List<string> files = new List<string>(); 
foreach (DirectoryInfo subDI in dI.GetDirectories()) 
{ 
     if ((subDI.Attributes & (FileAttributes.ReparsePoint | FileAttributes.System)) != 
     (FileAttributes)0) 
       continue; 
     files.Add(subDI.FullName); 
} 
+0

謝謝,這可能是我的應用程序更好的方法。謝謝+1 – Dave