【问题标题】:How to check in C# if user account is active如果用户帐户处于活动状态,如何签入 C#
【发布时间】:2012-09-07 13:14:17
【问题描述】:

如何从 C# 中检查本地用户帐户(即本地管理员帐户)是否处于活动状态?

我真正想要的是用 C# 替换“net user Administrator”命令的“Account Active”=“Yes”(或“No”)输出。

恐怕这个问题看起来像this 的一个重复问题,但我不知道为根 DirectoryEntry 对象的参数传递什么。尝试了不同的东西,如“ldap://”+ Environment.MachineName、“ldap://127.0.0.1”、“WinNT://”+ Environment.MachineName,但都没有奏效。在所有三种情况下,searcher.FindAll() 调用都会引发异常。

【问题讨论】:

  • 你遇到了什么异常?
  • 使用 "ldap://" + Environment.MachineName 我得到一个带有消息“服务器无法运行”的 COMException。和错误代码=-2147016646。与“ldap://127.0.0.1”相同。
  • 使用 "WinNT://" + Environment.MachineName 我收到 NotSupportedException 消息“提供程序不支持搜索并且无法搜索 WinNT://。”
  • 也尝试“WinNT://”+ Environment.MachineName +“,User”,但这会产生另一个 COMException,消息“未知错误 (0x80005000)”,ErrorCode=-2147463168。
  • 你可以使用 System.DirectoryServices.AccountManagement 吗?

标签: c# ldap


【解决方案1】:
class Program
{
    static void Main(string[] args)
    {

        // Create the context for the principal object. 
        PrincipalContext ctx = new PrincipalContext(ContextType.Machine);

        UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "Administrator");
        Console.WriteLine(String.Format("Administrator is enable: {0}", u.Enabled));

    }
}

【讨论】:

  • 谢谢,这也有效。但是 FindByIdentity 调用有时需要几秒钟才能返回结果。因此,尽管它的代码不错,但从性能角度来看,它并不是最好的解决方案。
  • 我也注意到了这一点,但我认为打开连接或类似的东西会有一些开销,因为当我进行后续查询时,它们的速度非常快。
【解决方案2】:

可以查询WMI的Win32_UserAccount

这是 MS 的 wmi 代码创建者作为参考吐出的样板;

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT Disabled FROM Win32_UserAccount WHERE name = 'alexk'");

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_UserAccount instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Disabled: {0}", queryObj["Disabled"]);
                    Console.ReadKey();
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}

(我会链接该工具,但像往常一样,msdn 链接已失效)

【讨论】:

  • 做到了!我不得不在 WMI 查询中添加“domain='”+ Environment.MachineName +“'”,以将结果限制为本地用户帐户,但它可以工作。非常感谢!
【解决方案3】:

试试这个。

 var server = "YOURMACHINENAME";
 var username = "Guest"; 
 var de = new DirectoryEntry {Path = "WinNT://" + server + ",computer"};
 var result = de.Children
     .Cast<DirectoryEntry>()
     .First<DirectoryEntry>(d => d.SchemaClassName == "User" && d.Properties["Name"].Value.ToString() == username);

 var flags = (int)result.Properties["UserFlags"].Value;
 var disabled = (flags & 2) == 2;

【讨论】:

    【解决方案4】:

    This 不太一样,但他们使用DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", computerName, username)); 会有帮助吗?

    【讨论】:

      【解决方案5】:

      考虑到是本地用户,需要调用win32 api函数NetGetUserInfo获取所需内容。

      pinvoke.net 中的示例几乎是你所需要的,但是你需要将 level 参数更改为 2 以获得neccesary info

      【讨论】:

      • 谢谢。这也可能有效。还没试过。我猜你指的是 USER_INFO_2.usri2_flags 字段(UF_ACCOUNTDISABLE)。虽然我最好避免使用 P/Invoke 并坚持使用纯 C# WMI 或 LDAP 解决方案。
      猜你喜欢
      • 1970-01-01
      • 2017-12-30
      • 2011-12-16
      • 2022-01-23
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多