title: A reliable way to obtain the Windows user display name
body: <p>I need to get the Display Name of the current user, and cannot find a solution that always works. Just for clarity, I'm not looking for the username. I need the "John Doe". The value displayed on the Start Menu.</p>
  
  <p>There are many posts about this question however none have solved my problem.</p>
  
  <p><a href="https://stackoverflow.com/questions/22187761/get-windows-user-display-name">Get Windows User Display Name</a> </p>
  
  <p><a href="https://stackoverflow.com/questions/6692767/how-do-i-get-the-ad-display-name-of-the-currently-logged-in-user">How do I get the AD Display Name of the currently logged in user</a></p>
  
  <p>These two posts lead me to: </p>
  
  <pre><code>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;
  </code></pre>
  
  <p>And this code works for the most part. However if the user's has disabled/stopped the Server service on his/her computer I get an exception saying "The Server service is not started."</p>
  
  <pre><code>System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName
  </code></pre>
  
  <p>Same error.</p>
  
  <p><a href="https://stackoverflow.com/questions/3438634/how-to-get-logged-in-users-full-name-in-windows">How to get logged-in user's full name in windows?</a></p>
  
  <pre><code>StringBuilder name = new StringBuilder(1024);
  uint userNameSize = (uint)name.Capacity;
  const int NameDisplay = 3;
  GetUserNameEx(NameDisplay, name, ref userNameSize)
  </code></pre>
  
  <p>Returns no error, but an empty string if the user is not on a domain.</p>
  
  <p><a href="https://stackoverflow.com/questions/3686201/how-do-you-read-the-users-display-first-and-last-name-on-all-versions-of-wind">How do you read the user's display (first and last) name on all versions of Windows reliably?</a></p>
  
  <pre><code>// get SAM compatible name &lt;server/machine&gt;\\&lt;username&gt;
  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);
      }
  }
  </code></pre>
  
  <p>With the above I get an ActiveDirectoryObjectNotFoundException with message "Domain controller not found in the domain.." when DomainController.FindOne is called.</p>
  
  <p>I haven't found a registry setting for the display name. </p>
  
  <p>I'm don't know what else to try. Please help.  </p>