5

我正在制作一个程序,它可以复制文件夹并将其传输到另一个位置,包括属性、权限、安全设置。

到目前为止,我让 Attribution 起作用,但在权限/安全设置方面存在问题。这是我的代码:

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);

任何人有任何建议让这个工作?谢谢大家的帮助。

4

4 回答 4

4

MSDN:如何将 ACL 信息从一个文件复制到另一个文件

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);
于 2013-07-03T15:09:25.967 回答
3

这似乎是以下内容的副本:

原始问题...

(来自原始问题的代码示例)

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);
    }
}

克里斯

于 2012-07-18T03:21:46.160 回答
2

基于Chris Keller 的答案的递归版本

    /// <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);
    }
于 2016-05-24T10:54:08.890 回答
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);
    }
于 2012-07-18T07:47:43.363 回答