你所在位置:首页C#.net开发 → C#使用DirectorySecurity的SetOwner设置文件夹所有者只能设为当前用户

C#使用DirectorySecurity的SetOwner设置文件夹所有者只能设为当前用户

发布时间:2019-05-15

看到有人问了这个问题,查询并实验后发现确实有这个问题,测试代码如下:

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#程序中模拟域帐户进行登录操作
下一篇:如何在全局程序集缓存(GAC)中安装DLL文件