我有一个C#winform应用程序,它将安装在Windows 7,Vista和XP机器上,32或64位,操作系统有英语,德语和西班牙语(以及将来的其他语言).
我需要在本地计算机上获取所有管理员和用户帐户名称的列表.我只需要一个帐户名列表,仅此而已.
问题是我的代码仅适用于英语操作系统.
有没有办法在本地机器上获取用户名,无论操作系统的语言如何,无论是XP,Vista还是7,无论是32位还是64位?
我读了一篇关于使用SID来获取本地管理员名称的帖子,以防它被重命名.使用SID可以帮助解决我的问题吗?
以下是我的代码.在德语OS计算机上,代码在"DirectoryEntry admGroup = localMachine.Children.Find("administrators","group");"行上失败.它最有可能失败,因为在德国操作系统中,"管理员","组"这两个词可能拼写不同.对于西班牙语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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使在使用英语的系统上,您也不希望按名称检索组 - 它们可以根据您的期望重命名.对于像管理员这样的内置组,您希望使用一个众所周知的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);
}
Run Code Online (Sandbox Code Playgroud)
编辑: @jyoung使用WellKnownSidType的建议比使用硬编码魔术值更好,String builtinAdminsSidString = "S-1-5-32-544";因此我更改了上面的示例代码.