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