I need to replace all the files in one directory with backup files in another directory. ALL the file properties/permissions/ownership must be retained. File.Copy, just like Windows Explorer, copies the files, clears all permissions, and changes the owner to myself.

I found an example on SO that SHOULD preserve its original permissions but doesn't: Copy a file with its original permissions

The code:

File.Copy(originFile, destinationFile);
FileInfo originFileInfo = new FileInfo(originFile);
FileInfo destinationFileInfo = new FileInfo(destinationFile);
FileSecurity ac1 = originFileInfo.GetAccessControl(AccessControlSections.All);
ac1.SetAccessRuleProtection(true, true);
destinationFileInfo.SetAccessControl(ac1);

I get a PrivilegeNotHeldException:

The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.

If I disable UAC I get this error instead:

The security identifier is not allowed to be the owner of this object.

I get this exception with AccessControlSections.All and AccessControlSections.Owner. The code works if I change the enum to AccessControlSections.Access, but only the permissions are retained, not the ownership. I am a local admin, and even when the destination is my local PC it doesn't work. And I am running Visual Studio 2010 as administrator.

有帮助吗?

解决方案 2

I didn't have permission to call GetAccessControl on any file that wasn't on my local machine (the first error), and I couldnt set the owner of any file I owned (the second error), I could only grant "take ownership" rights. Running the tool as the domain admin solved everything.

其他提示

You may need to explicitly acquire the 'SeSecurityPrivilege'. Perhaps the easiest way of doing that is to use Process Privileges.

// Untested code, but it might look like this...
// (Add exception handling as necessary)
Process process = Process.GetCurrentProcess();

using (new PrivilegeEnabler(process, Privilege.Security))
{
    // Privilege is enabled within the using block.
    File.Copy(originFile, destinationFile);
    FileInfo originFileInfo = new FileInfo(originFile);
    FileInfo destinationFileInfo = new FileInfo(destinationFile);
    FileSecurity ac1 = originFileInfo.GetAccessControl(AccessControlSections.All);
    ac1.SetAccessRuleProtection(true, true);
    destinationFileInfo.SetAccessControl(ac1);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top