C#使用DirectorySecurity的SetOwner设置文件夹所有者只能设为当前用户
看到有人问了这个问题,查询并实验后发现确实有这个问题,测试代码如下:
static void Main(string[] args) { try { string folderPath = @"e: estSecurity"; Directory.CreateDirectory(folderPath); DirectorySecurity defaultFSec = Directory.GetAccessControl(folderPath); IdentityReference newUser = new NTAccount("User2"); defaultFSec.SetOwner(newUser); Directory.SetAccessControl(folderPath, defaultFSec); } catch(Exception ex) { Console.WriteLine(ex); } Console.ReadLine(); }结果是System.InvalidOperationException: The security identifier is not allowed to be the owner of this object.
2005年在Microsoft Connect上就有人提出了这个问题,微软说下个版本将会考虑添加这个功能,然而现在似乎还不行。
当然总是有什么其他办法的,既然资源管理器可以做到,那么直接调用API就是一个可行的办法。Richard Willis给出了一个实现方法,我这里把他的代码转贴一下:
sealed class UnmanagedCode { [DllImport("kernel32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); // Use this signature if you do not want the previous state [DllImport("advapi32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, [MarshalAs(UnmanagedType.Bool)]bool disableAllPrivileges, ref TOKEN_PRIVILEGES newState, UInt32 bufferLength, IntPtr previousState, IntPtr returnLength); [DllImport("kernel32.dll", ExactSpelling = true)] static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] static extern bool OpenProcessToken (IntPtr processHandle, int desiredAccess, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] static extern bool LookupPrivilegeValue (string host, string name, ref LUID lpLuid); [StructLayout(LayoutKind.Sequential, Pack = 1)] struct TOKEN_PRIVILEGES { public UInt32 PrivilegeCount; public LUID Luid; public UInt32 Attributes; } [StructLayout(LayoutKind.Sequential)] public struct LUID { public uint LowPart; public补充:软件开发 , C# ,