문제

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