2012-07-18 95 views
3

我正在製作一個程序,它可以複製文件夾並將其傳輸到其他位置,包括屬性,權限,安全設置。C#複製文件夾到安全/權限設置的另一個目標

到目前爲止,我的署名工作正常,但遇到權限/安全設置問題。這裏是我的代碼:

Directory.CreateDirectory(Destination); 
DirectoryInfo DestAttribute = new DirectoryInfo(Destination); 
DestAttribute.Attributes = Source.Attributes; // Copies Attributes from Source to Dest 

AuthorizationRuleCollection Rule; 
DirectorySecurity DestSecurity = Source.GetAccessControl(); 
Rule = DestSecurity.GetAccessRules(true, true, typeof(NTAccount)); 
DestSecurity.AddAccessRule(Rule); 
DestAttribute.SetAccessControl(DestSecurity); 

任何人有任何建議讓這個工作? 謝謝大家的幫助。

+0

遞歸版本看來是重複的? [原來的問題...] [1] 克里斯 [1]:http://stackoverflow.com/questions/9995311/copying-folders-and-preserving-permissions – 2012-07-18 03:18:23

回答

0

過了一段時間,我終於想出瞭如何讓它工作。 目的是:從一個文件夾(不是文件)複製權限,並將其傳送到另一個文件夾。 (權限:帳戶設置,訪問規則等)

這是多麼我已經做到了:(幫助來自:http://forums.asp.net/t/1390009.aspx/1

private void PermissionGet(DirectoryInfo Source, DirectoryInfo Destination) 
    { 
     string Username; 
     DirectorySecurity SourceSecurity = Source.GetAccessControl(); 

     foreach (FileSystemAccessRule Rules in SourceSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount))) 
     { 
      Username = Rules.IdentityReference.Value; 
      PermissionSet(Username, Rules.FileSystemRights, Rules.AccessControlType, Destination); 
     } 
    } 

    private void PermissionSet(string Username, FileSystemRights Permission, AccessControlType Access, DirectoryInfo Destination) 
    { 
     DirectorySecurity Security = Destination.GetAccessControl(); 
     Security.AddAccessRule(new FileSystemAccessRule(Username, Permission, Access)); 
     Destination.SetAccessControl(Security); 
    } 
2

這似乎是一個重複:

Original Question...

(從原來的問題代碼示例)

FileInfo file1 = new FileInfo(@"c:\test.txt"); 
FileInfo file2 = new FileInfo(@"c:\test2.txt"); 
StreamReader sr1 = new StreamReader(file1.Open(FileMode.Open)); 
StreamWriter sw1 = new StreamWriter(file2.Open(FileMode.Create)); 
sw1.Write(sr1.ReadToEnd()); 
sr1.Close(); 
sw1.Close(); 
FileSecurity ac1 = file1.GetAccessControl(); 
ac1.SetAccessRuleProtection(true, true); 
file2.SetAccessControl(ac1); 

我總結了以下方法,它似乎你想要做什麼。 ..

private static void FolderCopy(String sourceFolder, String destinationFolder) 
{ 
    DirectoryInfo sourceDirectory = new DirectoryInfo(sourceFolder); 
    DirectoryInfo destinationDirectory; 

    if (!sourceDirectory.Exists) 
    { 
     throw new DirectoryNotFoundException("Source folder not found: " + sourceFolder); 
    } 

    if (!Directory.Exists(destinationFolder)) 
    { 
     destinationDirectory = Directory.CreateDirectory(destinationFolder); 
    } 
    else 
    { 
     destinationDirectory = new DirectoryInfo(destinationFolder); 
    } 

    DirectorySecurity security = sourceDirectory.GetAccessControl(); 

    security.SetAccessRuleProtection(true, true); 
    destinationDirectory.SetAccessControl(security); 

    var filesToCopy = sourceDirectory.GetFiles(); 

    foreach (FileInfo file in filesToCopy) 
    { 
     String path = Path.Combine(destinationFolder, file.Name); 
     FileSecurity fileSecurity = file.GetAccessControl(); 

     fileSecurity.SetAccessRuleProtection(true, true); 

     file.CopyTo(path, false); 

     FileInfo copiedFile = new FileInfo(path); 

     copiedFile.SetAccessControl(fileSecurity); 
    } 
} 

Chris

+0

你好,如果你覺得這是重複的,我很抱歉。 該方法是爲文件,我試圖將其轉換爲目錄版本,但沒有太多的運氣。在發佈這篇文章之前,我還查看了該主題以及所有其他鏈接。可悲的是,錯誤依然存在。 – FerX32 2012-07-18 03:31:40

+0

你能詳細說明出了什麼問題嗎? – 2012-07-18 06:32:40

+0

我剛添加了一個示例方法到我原來的答案。也許有了這個和你的原始代碼,你可以完成你的任務。 – 2012-07-18 06:41:22

3

MSDN: How To copy ACL information from one file to another

的SetAccessControl方法僅持續在創建對象後修改的DirectorySecurity對象。如果DirectorySecurity對象沒有被修改,它將不會被保存到文件中。因此,無法從一個文件中檢索DirectorySecurity對象,並將相同的對象重新應用到另一個文件。

從一個文件複製ACL信息到另一個:

  1. 請使用GetAccessControl方法來檢索從源文件DirectorySecurity對象。

  2. 爲目標文件創建一個新的DirectorySecurity對象。

  3. 使用源DirectorySecurity對象的GetSecurityDescriptorBinaryForm或GetSecurityDescriptorSddlForm方法檢索ACL信息。

  4. 使用SetSecurityDescriptorBinaryForm或SetSecurityDescriptorSddlForm方法將步驟3中檢索到的信息複製到目標DirectorySecurity對象。

  5. 使用SetAccessControl方法將目標DirectorySecurity對象設置爲目標文件。

例子:

DirectoryInfo dir1 = new DirectoryInfo(@"C:\Temp\Dir1"); 
DirectoryInfo dir2 = new DirectoryInfo(@"C:\Temp\Dir2"); 


DirectorySecurity ds1 = dir1.GetAccessControl(); 
DirectorySecurity ds2 = new DirectorySecurity(); 
ds2.SetSecurityDescriptorBinaryForm(ds1.GetSecurityDescriptorBinaryForm()); 
dir2.SetAccessControl(ds2); 
1

基於Chris Keller's答案

/// <summary> 
    /// Copy directory recursive with permissions, overwrite existing 
    /// </summary> 
    /// <param name="sourceFolder"></param> 
    /// <param name="destinationFolder"></param> 
    public static void CopyDirectory(string sourceFolder, string destinationFolder) 
    { 
     var sourceDirectory = new DirectoryInfo(sourceFolder); 
     if (!sourceDirectory.Exists) throw new DirectoryNotFoundException("Source folder not found: " + sourceFolder); 

     var destinationDirectory = !Directory.Exists(destinationFolder) ? Directory.CreateDirectory(destinationFolder) : new DirectoryInfo(destinationFolder); 

     CopyDirectory(sourceDirectory,destinationDirectory); 
    } 

    public static void CopyDirectory(DirectoryInfo sourceDirectory, DirectoryInfo destinationDirectory) 
    { 
     if(sourceDirectory == null) throw new ArgumentException("sourceDirectory"); 
     if(destinationDirectory == null) throw new ArgumentException("destinationDirectory"); 

     var security = sourceDirectory.GetAccessControl(); 

     security.SetAccessRuleProtection(true, true); 
     destinationDirectory.SetAccessControl(security); 

     var dirsToCopy = sourceDirectory.GetDirectories(); 
     foreach (var dirToCopy in dirsToCopy) 
     { 
      var destSubDirPath = Path.Combine(destinationDirectory.FullName,dirToCopy.Name); 
      var destinationSubDir = !Directory.Exists(destSubDirPath) ? Directory.CreateDirectory(destSubDirPath) : new DirectoryInfo(destSubDirPath); 
      CopyDirectory(dirToCopy,destinationSubDir); 
     } 

     var filesToCopy = sourceDirectory.GetFiles(); 

     foreach (var file in filesToCopy) 
     { 
      CopyFile(file, destinationDirectory.FullName); 
     } 
    } 

    private static void CopyFile(FileInfo file, string destinationDirectory) 
    { 
     var path = Path.Combine(destinationDirectory, file.Name); 
     var fileSecurity = file.GetAccessControl(); 

     fileSecurity.SetAccessRuleProtection(true, true); 

     file.CopyTo(path, true); 

     var copiedFile = new FileInfo(path); 

     copiedFile.SetAccessControl(fileSecurity); 
    }