你的意思是这一个属性较其他的要特殊吗?更改其他的属性都可以看到UAC值是即时更改的..

解决方案 »

  1.   

    是即时更改的,因为你说你知道获取,但是你没有成功,所以不知道你的代码是怎么写的。
    下面是的代码是测试所有本地用户(string sServername = ("127.0.0.1"))的,你稍微修改一下,应该可以在AD中使用。using System;
    using System.Collections;
    using System.Runtime.InteropServices;namespace UserAccount
    {
    class Program
    {
    public static void Main(string[] args)
    {
    GetUserFlags();
    Console.Write("Press any key to continue . . . ");
    Console.ReadKey(true);
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct USER_INFO_1
    {
    [MarshalAs(UnmanagedType.LPWStr)] public string sUsername;
    [MarshalAs(UnmanagedType.LPWStr)] public string sPassword;
    public uint uiPasswordAge;
    public uint uiPriv;
    [MarshalAs(UnmanagedType.LPWStr)] public string sHome_Dir;
    [MarshalAs(UnmanagedType.LPWStr)] public string sComment;
    public uint uiFlags;
    [MarshalAs(UnmanagedType.LPWStr)] public string sScript_Path;
    }

    //uiPriv
    const uint USER_PRIV_GUEST = 0;
    const uint USER_PRIV_USER = 1;
    const uint USER_PRIV_ADMIN = 2; //uiFlags (flags)
    const uint UF_DONT_EXPIRE_PASSWD = 0x10000;
    const uint UF_MNS_LOGON_ACCOUNT = 0x20000;
    const uint UF_SMARTCARD_REQUIRED = 0x40000;
    const uint UF_TRUSTED_FOR_DELEGATION = 0x80000;
    const uint UF_NOT_DELEGATED = 0x100000;
    const uint UF_USE_DES_KEY_ONLY = 0x200000;
    const uint UF_DONT_REQUIRE_PREAUTH = 0x400000;
    const uint UF_PASSWORD_EXPIRED = 0x800000;
    const uint UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000;
    const uint UF_NO_AUTH_DATA_REQUIRED = 0x2000000;
    const uint UF_PARTIAL_SECRETS_ACCOUNT = 0x4000000;
    const uint UF_USE_AES_KEYS = 0x8000000; //uiFlags (choice)
    const uint UF_SCRIPT = 0x0001;
    const uint UF_ACCOUNTDISABLE = 0x0002;
    const uint UF_HOMEDIR_REQUIRED = 0x0008;
    const uint UF_LOCKOUT = 0x0010;
    const uint UF_PASSWD_NOTREQD = 0x0020;
    const uint UF_PASSWD_CANT_CHANGE = 0x0040;
    const uint UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x0080;
    const uint UF_TEMP_DUPLICATE_ACCOUNT = 0x0100;
    const uint UF_NORMAL_ACCOUNT = 0x0200;
    const uint UF_INTERDOMAIN_TRUST_ACCOUNT = 0x0800;
    const uint UF_WORKSTATION_TRUST_ACCOUNT = 0x1000;
    const uint UF_SERVER_TRUST_ACCOUNT = 0x2000; [DllImport("Netapi32.dll")]
    extern static int NetUserEnum(
    [MarshalAs(UnmanagedType.LPWStr)]
    string servername,
    int level,
    int filter,
    out IntPtr bufptr,
    int prefmaxlen,
    out int entriesread,
    out int totalentries,
    out int resume_handle); [DllImport("Netapi32.dll")]
    extern static int NetApiBufferFree(IntPtr Buffer); public static void GetUserFlags(/*string strServerName, string strUserName*/)
    {
    ArrayList users = new ArrayList();
    int EntriesRead;
    int TotalEntries;
    int Resume;
    IntPtr bufPtr;
    string sServername = ("127.0.0.1"); // local NetUserEnum(sServername,1, 2, out bufPtr, -1, out EntriesRead, out TotalEntries, out Resume);
    if(EntriesRead> 0)
    {
    USER_INFO_1[] Users = new USER_INFO_1[EntriesRead];
    IntPtr iter = bufPtr;
    for(int i=0; i < EntriesRead; i++)
    {
    Users[i] = (USER_INFO_1)Marshal.PtrToStructure(iter, typeof(USER_INFO_1));
    //Console.WriteLine(Users[i].uiFlags.ToString());

    string strTmp = Users[i].sUsername;
    uint lngFlags = Users[i].uiFlags;
    // if (Convert.ToBoolean(lngFlags & UF_SCRIPT))
    // {
    // strTmp = strTmp + "\r\n" + "Script is executed";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Script is NOT executed";
    // }
    //
    // if (Convert.ToBoolean(lngFlags & UF_ACCOUNTDISABLE))
    // {
    // strTmp = strTmp + "\r\n" + "Account is disabled";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Account is NOT disabled";
    // }
    //
    // if (Convert.ToBoolean(lngFlags & UF_HOMEDIR_REQUIRED))
    // {
    // strTmp = strTmp + "\r\n" + "Home directory is required";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Home directory is NOT required";
    // }
    //
    //
    // if (Convert.ToBoolean(lngFlags & UF_LOCKOUT))
    // {
    // strTmp = strTmp + "\r\n" + "Account is locked out";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Account is NOT locked out";
    // }
    //
    // if (Convert.ToBoolean(lngFlags & UF_PASSWD_NOTREQD))
    // {
    // strTmp = strTmp + "\r\n" + "Password is NOT required";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Password is required";
    // }

    if (Convert.ToBoolean(lngFlags & UF_PASSWD_CANT_CHANGE))
    {
    strTmp = strTmp + "\r\n" + "User cannot change password";
    }
    else
    {
    strTmp = strTmp + "\r\n" + "User can change password";
    }

    // if (Convert.ToBoolean(lngFlags & UF_DONT_EXPIRE_PASSWD))
    // {
    // strTmp = strTmp + "\r\n" + "Password never expires";
    // }
    // else
    // {
    // strTmp = strTmp + "\r\n" + "Password does expire";
    // }
    Console.WriteLine(strTmp); iter = (IntPtr)((int)iter + Marshal.SizeOf(typeof(USER_INFO_1))); users.Add(Users[i]);
    }
    NetApiBufferFree(bufPtr);
    }
    }
    }
    }你的意思是这一个属性较其他的要特殊吗?更改其他的属性都可以看到UAC值是即时更改的..
      

  2.   

    我是用的一个工具(Active Directory Explorer)看UAC值的,这个应该没问题吧?我现在就试试你的代码,万分感谢!
      

  3.   


    用你的代码确确实实可以获取,并且lngFlags这个值就是UserAccountControl值吗?我发现他跟我用工具看到的不一样.......难道真是工具问题?并且我发现你的代码我都看不懂,大神顺便给你看看我的代码有什么问题吧,我的代码获取UserAccountControl的值跟我用工具获取的不一样...string sAMAccountName="username"//要查询的用户登录名
    object obj = ConfigurationManager.GetSection("directoryEntries");
    DirectoryEntryConfigurationSection section = obj as DirectoryEntryConfigurationSection;
    using (DirectoryEntry rootEntry = new DirectoryEntry(section.RootPath))
    {
        rootEntry.UsePropertyCache = false;//不使用缓存
        using (DirectorySearcher searcher = new DirectorySearcher(rootEntry))
        {
            searcher.Filter = string.Format("(&(objectCategory=person)(sAMAccountName={0}))", sAMAccountName);
            searcher.PropertiesToLoad.Add("sn");
            searcher.PropertiesToLoad.Add("givenName");
            searcher.PropertiesToLoad.Add("userAccountControl");
            searcher.CacheResults = false;
            searcher.Asynchronous = false;
            using (SearchResultCollection results = searcher.FindAll())
            {
                if (results.Count > 0)
                {
                    ADUserInfo ui = new ADUserInfo
                    {
                        Sn = results[0].Properties["sn"].ToStr(),
                        GivenName = results[0].Properties["givenName"].ToStr(),
                        Mail = results[0].Properties["mail"].ToStr(),
                        UserAccountControl = results[0].Properties["userAccountControl"].ToInt32(),
                        PwdLastSet = results[0].Properties["pwdLastSet"].ToLong()
                    };
                    return ui;
                }
                return null;
            }
        }
    }
      

  4.   

    说错了,我的代码获取UserAccountControl的值跟我用Active Directory Explorer获取的一样,跟你代码里面的lngFlags不一样...
      

  5.   

    上面代码里面的lngFlags是USER_INFO_1结构里面的,代码调用的是WinAPI里面的函数。
    你的代码试一下把results[0].Properties["userAccountControl"]改成results[0].Properties["userAccountControl"][0]
      

  6.   

    噢噢噢,我懂了.....
    我不确定这个UserAccountControl是否真的和那个属性有关联,我想使用你的代码,但是我怕出现什么权限问题,你的代码是不是只适用于域控上面?ToInt32是我写的扩展方法,详细如下public static int ToInt32(this System.DirectoryServices.ResultPropertyValueCollection obj)
    {
        if (obj.Count > 0)
            return Convert.ToInt32(obj[0]);
        return 0;
    }
      

  7.   

    NetUserEnum的第一个参数就是目标服务器,不一定需要程序在域控上面运行的。
    当然,最简单的方法就是你自己编译在不同机器上运行一下,把上面代码的GetUserFlags函数中的参数string strServerName注释取消,并注释掉string sServername = ("127.0.0.1"); // local这行,然后看看有什么输出或错误提示。
    关于其他网络函数,你也可以先看看这篇C#中使用网络函数 (第一部分 用户函数)[翻译]