2015-01-16 1 views
7

Ho bisogno di ottenere il nome visualizzato dell'utente corrente e non riesco a trovare una soluzione che funzioni sempre. Solo per chiarezza, non sto cercando il nome utente. Ho bisogno del "John Doe". Il valore visualizzato nel menu Start.Un modo affidabile per ottenere il nome visualizzato dell'utente di Windows

Ci sono molti post su questa domanda, ma nessuno ha risolto il mio problema.

Get Windows User Display Name

How do I get the AD Display Name of the currently logged in user

Questi due messaggi mi portano a:

PrincipalContext context = domain.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase) ? 
    new PrincipalContext(ContextType.Machine) : 
    new PrincipalContext(ContextType.Domain, domain); 

UserPrincipal userPrincipal = new UserPrincipal(context) { SamAccountName = username }; 
PrincipalSearcher searcher = new PrincipalSearcher(userPrincipal); 
userPrincipal = searcher.FindOne() as UserPrincipal; 

string displayName = userPrincipal.DisplayName; 

E questo codice funziona per la maggior parte. Tuttavia, se l'utente ha disabilitato/interrotto il servizio Server sul proprio computer, viene visualizzata un'eccezione che dice "Il servizio Server non è avviato."

System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName 

Stesso errore.

How to get logged-in user's full name in windows?

StringBuilder name = new StringBuilder(1024); 
uint userNameSize = (uint)name.Capacity; 
const int NameDisplay = 3; 
GetUserNameEx(NameDisplay, name, ref userNameSize) 

non restituisce alcun errore, ma una stringa vuota se l'utente non è in un dominio.

How do you read the user's display (first and last) name on all versions of Windows reliably?

// get SAM compatible name <server/machine>\\<username> 
if (0 != GetUserNameEx(2, username, ref userNameSize)) 
{ 
    IntPtr bufPtr; 
    try 
    { 
     string domain = Regex.Replace(username.ToString(), @"(.+)\\.+", @"$1"); 
     DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domain); 
     DomainController dc = DomainController.FindOne(context); 

     if (0 == NetUserGetInfo(dc.IPAddress, 
        Regex.Replace(username.ToString(), @".+\\(.+)", "$1"), 
        10, out bufPtr)) 
     { 
      var userInfo = (USER_INFO_10) Marshal.PtrToStructure(bufPtr, typeof (USER_INFO_10)); 
      return Regex.Replace(userInfo.usri10_full_name, @"(\S+), (\S+)", "$2 $1"); 
     } 
    } 
    finally 
    { 
     NetApiBufferFree(out bufPtr); 
    } 
} 

Con quanto sopra ottengo un ActiveDirectoryObjectNotFoundException con il messaggio "controller di dominio non trovato nel dominio .." quando DomainController.FindOne viene chiamato.

Non ho trovato un'impostazione di registro per il nome visualizzato.

Non so cos'altro provare. Per favore aiuto.

+1

Non so se troverai una soluzione al 100%; poi di nuovo, quali probabilità vedete con alcuni dei casi di branca (ad esempio utente non su un dominio)? Potrebbe non valerne la pena se l'impatto fosse solo di pochi utenti. –

risposta

3

Tutti i metodi sopra indicati funzioneranno solo se si è su un dominio. In caso contrario, è necessario fare affidamento sull'archivio dell'account utente locale. I seguenti dettagli su come recuperare queste informazioni: How can I get a list Local Windows Users (Only the Users that appear in the windows Logon Screen). Tuttavia, in una situazione di dominio, l'account dell'utente non sarà nell'archivio locale.

Se ci si trova su un dominio ma non si è connessi al controller di dominio, il nome visualizzato non sarà immediatamente disponibile. Queste informazioni sono memorizzate sul controller di dominio, non sul computer dell'utente locale. Se i tuoi utenti si trovano su un dominio, in realtà non dovrebbero essere in grado di disabilitare il servizio Server (utilizzare oggetti Criteri di gruppo). Inoltre, perdono molto più della possibilità di recuperare il proprio account utente disabilitando quel servizio.

Vorrei verificare la disponibilità del dominio prima di provare a ottenere il nome visualizzato. Se fallisce, visualizza un messaggio che indica l'errore. Ci sono potenzialmente troppi casi di spigoli qui per farlo funzionare tenendo conto di tutti loro. Andare con lo scenario in cui si intende utilizzare il programma e fornire un messaggio di errore per gli altri.