2009-11-04 1 views
7

Ho un'applicazione che controlla se un utente esiste (se non lo crea) ogni volta che si avvia. Questo è fatto come segue:Un modo più rapido per scoprire se un utente esiste su un sistema?

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; 
} 

Il problema è nella maggior parte dei sistemi in cui è distribuito. Questo può richiedere 6 - 10 secondi, che è troppo lungo ... Ho bisogno di trovare un modo per ridurlo (il più possibile). C'è un migliore o più veloce modo che posso usare per verificare se un utente esiste sul sistema o no?

So che ci sono altri modi per risolvere questo, come se le altre applicazioni dormissero per 10 secondi, o che questo strumento inviasse un messaggio quando è pronto, ecc ... Ma se posso ridurre notevolmente il tempo necessario per trovare l'utente, mi renderebbe la vita molto più facile.

+0

Siete alla ricerca di un utente locale sulla macchina? –

+0

Sì, solo utente locale – Shaitan00

+0

L'utente deve esistere prima che l'applicazione termini l'avvio? –

risposta

20

.NET 3.5 supporta nuove classi AD durante la ricerca nello spazio dei nomi System.DirectoryServices.AccountManagement.

Per utilizzarlo, è necessario aggiungere "System.DirectoryServices.AccountManagement" come riferimento E aggiungere l'istruzione 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

Per le versioni di .NET precedenti alla 3.5, ecco un esempio pulito che ho trovato su dotnet-snippets

DirectoryEntry dirEntryLocalMachine = 
    new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"); 

bool UserExists = 
    dirEntryLocalMachine.Children.Find(userIdentity, "user") != null; 
+0

Purtroppo non posso usare .NET 3.5, sono bloccato con .NET 2.0 ... Esiste un equivalente? – Shaitan00

+0

Ho aggiornato la mia risposta per includere un ottimo articolo su esattamente quello che stai cercando. È molto simile al tuo metodo attuale, ma invece di enumerare attraverso ogni oggetto, usa la funzione Children.Find(). Si prega di fare clic sul collegamento in quanto l'articolo ha una classe completa per gestire questo ed è molto bello. –

+0

Funziona - ma richiede altrettanto tempo ... – Shaitan00

1

Il seguente in un comando nuovamente visualizzato il prompt 1 se "nome utente" esiste.

utente rete | trova "nome utente"/c

+1

Che cosa ha a che fare con la ricerca di un utente in C#? –

+0

Potrebbe essere usato da C#, ma temo che questa non sia la soluzione più accurata. – Henri

+0

Non voglio iniziare a generare shell di comandi per usare l'utente di rete, qualcosa con C# sarebbe meglio. – Shaitan00

5

Si desidera utilizzare DirectorySearcher.

Qualcosa di simile a questo:

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; 
     } 
    } 
} 

che dovrebbe essere più veloce. Inoltre, puoi ridurre le proprietà se tutto quello che stai facendo è il controllo dell'esistenza.

+0

Questo è un metodo rapido E funziona con le versioni .NET precedenti alla 3.5 (se questo è il tuo ambiente). –

+0

Dove è impostato il risultato? – Shaitan00

+0

Non ho familiarità con DirectoryEntry (directory attiva e roba), quali proprietà non sono necessarie per essere certi al 100% che l'utente non esiste già se ho solo lo UserName da seguire? – Shaitan00

0

Questo dovrebbe farlo (quando non è possibile utilizzare System.DirectoryServices.AccountManagement):

static bool userExists(string sUser) 
{ 
    using (var oUser = new DirectoryEntry("WinNT://" + Environment.MachineName + "/" + sUser + ",user")) 
    { 
     return (oUser != null); 
    } 
}