如何获取XP,Vist和7中的所有用户帐户名,32位或64位以及任何操作系统语言

我有一个C#winform应用程序,将安装在Windows 7,Vista和XP机器上,32或64位,操作系统使用英语,德语和西class牙语(以及将来的其他语言)。

我需要在本地计算机上获取所有管理员和用户帐户名称的列表。 我只需要一个帐户名列表,仅此而已。

问题是我的代码仅适用于英语操作系统。

有没有办法在本地机器上获取用户名,无论操作系统的语言如何,无论是XP,Vista还是7,无论是32位还是64位?

我读了一篇关于使用SID来获取本地管理员名称的post,以防它被重命名。 使用SID可以帮助解决我的问题吗?

以下是我的代码。 在德语操作系统计算机上,代码在“DirectoryEntry admGroup = localMachine.Children.Find(”administrators“,”group“);”行上失败。 它最有可能失败,因为在德国操作系统中,“管理员”,“组”这两个词可能拼写不同。 对于西class牙语OS来说也是如此。

我的32位操作系统代码:

DirectoryEntry localMachine = new DirectoryEntry( "WinNT://" + Environment.MachineName); DirectoryEntry admGroup = localMachine.Children. Find("administrators", "group"); object adminmembers = admGroup.Invoke("members", null); DirectoryEntry userGroup = localMachine.Children.Find("users", "group"); object usermembers = userGroup.Invoke("members", null); //Retrieve each user name. foreach (object groupMember in (IEnumerable)adminmembers) { DirectoryEntry member = new DirectoryEntry(groupMember); if (!(member.Name == "admin" || member.Name == "Domain Admins")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = member.Name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } foreach (object groupMember in (IEnumerable)usermembers) { DirectoryEntry member = new DirectoryEntry(groupMember); if (!(member.Name == "ACTUser" || member.Name == "ASPNET" || member.Name == "Domain Users" || member.Name == "Authenticated Users" || member.Name == "INTERACTIVE" || member.Name == "SQLDebugger")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = member.Name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } 

我的64位操作系统代码:

 SelectQuery query = new SelectQuery("Win32_UserAccount"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); foreach (ManagementObject envVar in searcher.Get()) { str_name = envVar["Name"].ToString(); if (!(str_name == "admin" || str_name == "Domain Admins")) { if (!(str_name == "ACTUser" || str_name == "ASPNET" || str_name == "Domain Users" || str_name == "Authenticated Users" || str_name == "INTERACTIVE" || str_name == "SQLDebugger")) { if (!(str_name == "HomeGroupUser$")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = str_name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } } } 

即使在使用英语的系统上,您也不希望按名称检索组 – 它们可以根据您的期望重命名。 对于像管理员这样的内置组,您希望使用一个众所周知的SID ,无论使用何种语言命名该组,它都可以使用。

这是检索所需数据的一种方法…

 SecurityIdentifier builtinAdminSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null); PrincipalContext ctx = new PrincipalContext(ContextType.Machine); GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, builtinAdminsSid.Value); foreach (Principal p in group.Members) { Console.WriteLine(p.Name); } 

编辑: @jyoung使用WellKnownSidType的建议比使用String builtinAdminsSidString = "S-1-5-32-544";这样的硬编码魔术值更好String builtinAdminsSidString = "S-1-5-32-544"; 所以我改变了上面的示例代码。

这个如何获取内置管理员名称的示例可能会有所帮助。

 var builtinAdministratorsName = new SecurityIdentifier( WellKnownSidType.BuiltinAdministratorsSid, null). Translate(typeof(NTAccount)).Value; 

请试试这个:

 using System.Management; using (var accountSearcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_UserAccount WHERE LocalAccount=True")) using (var accountCollection = accountSearcher.Get()) foreach (var account in accountCollection) this.listBox1.Items.Add(account["Name"].ToString()); 

使用GetSystemUILanguage获取语​​言然后使用switch case(你自己必须搜索文件夹名称)。