我找到了一种将ntfs权限信息从一个现有文件夹复制到新创建的文件夹的方法 - 我不确定它是否正在做它应该做的工作。也许可以看看这个方法并给出一些评论:
private static void CopySecurityInformation(String source, String dest)
{
FileSecurity fileSecurity = File.GetAccessControl(
source,
AccessControlSections.All);
FileAttributes fileAttributes = File.GetAttributes(source);
File.SetAccessControl(dest, fileSecurity);
File.SetAttributes(dest, fileAttributes);
}
感谢您的帮助, 丹尼尔
答案 0 :(得分:2)
我尝试遵循OP建议的模式来复制文件的ACL和属性,并在我们的应用程序中发现了一些问题。希望这些信息有助于其他人。
根据MSDN,使用上面显示的File.SetAccessControl()
方法不起作用。
SetAccessControl方法仅保留FileSecurity对象 在创建对象后进行了修改。如果是FileSecurity对象 尚未修改,它不会被持久保存到文件中。因此, 无法从一个文件中检索FileSecurity对象 将同一个对象重新应用到另一个文件。
必须为目标文件创建一个新的FileSecurity
对象,并为其分配源FileSecurity
对象的副本。
这是一个可以在我们的应用程序中运行的模式示例。
public static void CopyFile(string source, string destination)
{
// Copy the file
File.Copy(source, destination, true);
// Get the source file's ACLs
FileSecurity fileSecuritySource = File.GetAccessControl(source, AccessControlSections.All);
string sddlSource = fileSecuritySource.GetSecurityDescriptorSddlForm(AccessControlSections.All);
// Create the destination file's ACLs
FileSecurity fileSecurityDestination = new FileSecurity();
fileSecurityDestination.SetSecurityDescriptorSddlForm(sddlSource);
// Set the destination file's ACLs
File.SetAccessControl(destination, fileSecurityDestination);
// copy the file attributes now
FileAttributes fileAttributes = File.GetAttributes(source);
File.SetAttributes(destination, fileAttributes);
}
修复第一个问题后,我们发现未复制所有者属性。相反,在我们的例子中,目标文件由管理员拥有。要解决此问题,该流程需要启用SE_RESTORE_NAME权限。查看pinvoke.net上的AdjustTokenPrivileges
以获取一个完整的Privileges类,它可以轻松设置权限。
我们必须处理的最后一件事是UAC。如果用户在UAC下运行,我们需要使用管理权限重新启动我们的应用程序。以下是我们的应用程序中的另一个示例,该示例涉及使用提升的权限重新启动应用程序。
private static void RelaunchWithAdministratorRights(string[] args)
{
// Launch as administrator
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.UseShellExecute = true;
processStartInfo.WorkingDirectory = Environment.CurrentDirectory;
string executablePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
processStartInfo.FileName = executablePath;
processStartInfo.Verb = "runas";
if (args != null && args.Count() > 0)
{
string arguments = args[0];
for (int i = 1; i < args.Count(); i++)
arguments += " " + args[i];
processStartInfo.Arguments = arguments;
}
try
{
using (Process exeProcess = Process.Start(processStartInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// The user refused to allow privileges elevation. Do nothing and return directly ...
}
Environment.Exit(0);
}
我们是一个控制台应用,因此我们需要将args
方法中的Main
参数传递给RelaunchWithAdministratorRights(args)
。非控制台应用程序可以传递null。我们从RelaunchWithAdministratorRights
块中调用catch
,如下所示:
try
{
...
}
catch (SecurityException)
{
RelaunchWithAdministratorRights(args);
return;
}
在我们的应用中,我们只需在调用RelaunchWithAdministratorRights
后返回,即可退出缺少权限的应用实例。根据您的应用,您可能更愿意throw
出路。无论如何,从RelaunchWithAdministratorRights
返回后,您不希望此实例继续处理。
享受!
答案 1 :(得分:1)
它不仅仅是复制NTFS权限。它还复制文件的属性。我不确定它是否复制了继承权限,但是运行一次,你应该能够找到它。
请注意,复制权限本身需要特殊权限(管理员当然也有这些权限),请确保运行此方法的进程具有查询,查看和设置这些对象的权限所需的权限。