2015-01-16 2 views
7

Мне нужно получить отображаемое имя текущего пользователя и не может найти решение, которое всегда работает. Просто для ясности я не ищу имя пользователя. Мне нужен «Джон Доу». Значение, отображаемое в меню «Пуск».Надежный способ получить отображаемое имя пользователя Windows

Есть много сообщений по этому вопросу, однако никто не решил мою проблему.

Get Windows User Display Name

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

Эти две должности заставляют меня:

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; 

И этот код работает по большей части. Однако, если пользователь отключил/остановил службу сервера на своем компьютере, я получаю исключение: «Служба сервера не запущена».

System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName 

Такая же ошибка.

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) 

Возвращает не ошибка, но пустая строка, если пользователь не в домене.

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

С выше я получаю ActiveDirectoryObjectNotFoundException с сообщением «контроллер домена не найден в домене ..» когда DomainController.FindOne называется.

Я не нашел параметр реестра для отображаемого имени.

Я не знаю, что еще попробовать. Пожалуйста помоги.

+1

Я не знаю, найдете ли вы 100% -ное решение; опять же, какие вероятности вы видите с некоторыми случаями ветвления (например, пользователь не в домене)? Это может не стоить усилий, если воздействие будет всего лишь несколькими пользователями. –

ответ

3

Все вышеуказанные методы будут работать только в том случае, если вы находитесь в домене. Если вы этого не сделаете, вы должны опираться на локальное хранилище учетных записей пользователей. Ниже приведена информация о том, как получить эту информацию: How can I get a list Local Windows Users (Only the Users that appear in the windows Logon Screen). Однако в ситуации с доменом учетная запись пользователей не будет находиться в локальном хранилище.

Если вы находитесь в домене, но не подключены к контроллеру домена, отображаемое имя не будет доступно вам. Эта информация хранится на контроллере домена, а не на компьютере локального пользователя. Если ваши пользователи находятся в домене, они действительно не должны отключать службу сервера (использовать объекты групповой политики). Кроме того, они теряют гораздо больше, чем возможность восстановить свою учетную запись пользователя, отключив эту службу.

Я хочу проверить наличие домена, прежде чем пытаться получить отображаемое имя. В случае сбоя отобразится сообщение об ошибке. Здесь потенциально слишком много случаев кросс, чтобы заставить их работать на всех из них. Перейдите со сценарием, который вы планируете использовать в программе, и дайте сообщение об ошибке для остальных.

Смежные вопросы