我有一个应用程序,每次启动时都会检查用户是否存在(如果不创建)。操作如下:
bool bUserExists = false;
DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
DirectoryEntries dirEntries = dirEntryLocalMachine.Children;
foreach (DirectoryEntry dirEntryUser in dirEntries)
{
bUserExists = dirEntryUser.Name.Equals("UserName",
StringComparison.CurrentCultureIgnoreCase);
if (bUserExists)
break;
}
问题出现在部署它的大多数系统上。这可能需要 6 - 10 秒,这太长了......我需要找到一种方法来减少这个时间(尽可能多)。有没有一种更好或更快的方法可以用来验证系统上是否存在用户?
我知道还有其他方法可以解决这个问题,比如让其他应用程序休眠 10 秒,或者让这个工具在准备好时发送消息等等......但是如果我可以大大减少找到所需的时间用户,这会让我的生活变得更轻松。
.NET 3.5 支持 System.DirectoryServices.AccountManagement
命名空间下的新AD 查询类。
要使用它,您需要添加“System.DirectoryServices.AccountManagement”作为引用并添加
using
语句。
using System.DirectoryServices.AccountManagement;
using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
{
UserPrincipal up = UserPrincipal.FindByIdentity(
pc,
IdentityType.SamAccountName,
"UserName");
bool UserExists = (up != null);
}
< .NET 3.5
对于 3.5 之前的 .NET 版本,这是我在 dotnet-snippets
上找到的一个简单示例DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
bool UserExists =
dirEntryLocalMachine.Children.Find(userIdentity, "user") != null;
您想使用目录搜索器。
类似这样的:
static bool userexists( string strUserName ) {
string adsPath = string.Format( @"WinNT://{0}", System.Environment.MachineName );
using( DirectoryEntry de = new DirectoryEntry( adsPath ) ) {
try {
return de.Children.Find( strUserName ) != null;
} catch( Exception e ) {
return false;
}
}
}
那应该更快。另外,如果您所做的只是检查是否存在,则可以减少属性。
如果“用户名”存在,命令提示符中的以下内容将返回 1。
网络用户 |找到“用户名”/c
另一种方式如下(支持本地或域用户):
bool UserExists(string userName)
{
var user = new NTAccount(userName);
try
{
var sid = (SecurityIdentifier)user.Translate(typeof(SecurityIdentifier));
return true;
}
catch (IdentityNotMappedException)
{
return false;
}
}
用户可能不合格,或者通过机器/域名合格(
DOMAIN\UserName
)。如果您需要专门检测本地计算机上是否存在该帐户,请通过 Environment.MachineName
($"{Environment.MachineName}\\{userName}"
) 对其进行限定。
@kenny 答案的 C# 实现
static string chkAdmin(string args)
{
var admin_info = "/C" + args;
var process_info = new System.Diagnostics.ProcessStartInfo("cmd.exe");
process_info.Arguments = admin_info;
process_info.CreateNoWindow = true;
process_info.RedirectStandardOutput = true;
process_info.UseShellExecute = false;
var cmd = System.Diagnostics.Process.Start(process_info);
var output = cmd.StandardOutput.ReadToEnd();
cmd.WaitForExit();
return output;
}
private void button1_Click(object sender, EventArgs e)
{
int flag;
flag = Convert.ToInt32(chkAdmin("net user | find \"Administrator\" /c"));
if (flag == 1)
{
MessageBox.Show("Found");
}
else
{
MessageBox.Show("Not Found");
}
}
将“管理员”替换为您的目标用户帐户。