看到有人問了這個問題,查詢並實驗後發現確實有這個問題,測試代碼如下:
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