11

I know that the following function returns the current Windows user's name in domain\username format.

Convert.ToString( WindowsIdentity.GetCurrent().Name );

But how do I obtain the user's name in username@domain format?

EDIT:

I'm responding in this edit as everyone who has replied has the same basic idea.

From what I've been given to understand, parsing the name from domain\username format and constructing it as username@domain is not safe or advised. I believe this is so because there is no guarantee that the two domain names are the same in the different formats. For example, in the company where I work, the domain part of the domain\username format is based upon deparment, but in the username@domain, it's the company name. It's the kind of thing that requires a DNS lookup.

I was hoping that there was an API that did this DNS lookup. I guess I should have put this information into my original question. Sorry.

Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123

7 Answers7

13

Something like this should work...

string[] temp = Convert.ToString(WindowsIdentity.GetCurrent().Name).Split('\\');
string userName = temp[1] + "@" + temp[0];
Kevin
  • 704
  • 3
  • 4
5

All of the code to take the name in Domain\user name format and parse it will not work in all situations. The answer is you have to make calls to Active Directory to get the User Principal Name. It turns out that I can't rely on Active Directory being installed on the desktop, since many police departments don't install the directory on their laptops in case it is stolen while a cop is not in the car. (Talk about gutsy, stealing a computer out of a police vehicle!)

We have come up with our own solution for our situation. We store the user names in our database in Domain\user name format. When the program starts up, it checks to see if the current windows user name (in the same format) is in the database. If it is, the program uses that user as the current user and runs. If the current Windows user is not in our database, the program falls back to our previous code.

This way, the user can log into the machine using any format for their user name and they authenticate with Windows. Our program always gets the user name in the same format and it always checks the user name in that format. Windows authenticates the user and not us.

Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123
  • 1
    For the record, Active Directory is a server component so it is never "installed on the desktop". Probably the issue was that you couldn't rely on having network connectivity to the domain controllers. – Harry Johnston Sep 11 '12 at 22:06
  • Yes, that's exactly right. The laptops are in police cars. Not all of them have any kind of connectivity while on the road, and those that do may be unreliable. – Tony Vitabile Sep 13 '12 at 15:28
  • So you're telling us basically: `the police department doesn't want usernames stored locally for security reasons, but I'm ignoring that requirement to make my program work`? – StoriKnow Oct 05 '12 at 14:30
  • No, that's not right. As has been pointed out, active directory runs on a server as a service. The computer is in a vehicle and may not have reliable connection to the active directory server, even if it does have a cell card installed. All I have is a list of users who have access to the application. I don't know their passwords or even their email addresses, just their user names and what privileges they have. It's the only way to make sure that the user logged into the computer has access to anything. – Tony Vitabile Oct 05 '12 at 15:29
4

You could split the name using \ as the delimiter, then reverse the order like so:

string[] splitName = WindowsIdentity.GetCurrent().Name.Split('\\');
//check that splitName contains at least 2 values before using
string name = (splitName.Length > 1) ? splitName[1] + "@" + splitName[0] : null;

It's important to note that a double backslash \\ is required because a backslash is a special character. We add the second backslash in the above example to escape the special character and use it as a regular character.

StoriKnow
  • 5,738
  • 6
  • 37
  • 46
4
var input =  WindowsIdentity.GetCurrent().Name ;
string[] tab = input.Split('\\');
var result = tab[1] + "@" +  tab[0];
Aghilas Yakoub
  • 28,516
  • 5
  • 46
  • 51
4

Use

System.DirectoryServices.AccountManagement.UserPrincipal.Current.UserPrincipalName

This returns the UPN of the current user. Requires a reference to System.DirectoryServices.AccountManagement.

Simon Giles
  • 776
  • 9
  • 10
0

Something along these lines.

var nameParts = WindowsIdentity.GetCurrent().Name.Split(@"\");
string name = nameParts.Length == 1 
    ? nameParts  
    : string.format("{0}@{1}",nameParts[1],nameParts[0]);
Koopakiller
  • 2,838
  • 3
  • 32
  • 47
  • Your code format got messed up. Also, why does your code assume that `nameParts.Length == 1` signifies safe use of an array that should have a length of **at least** (and probably no more than) 2. In your assumption, it might be more appropriate to check the UpperBound like so `(nameParts.GetUpperBound(0) == 1)` – StoriKnow Aug 28 '12 at 20:20
  • Your code won't compile. you cannot assign `nameParts` which is a string array to a string. Also, `string.format` does not exist, it's `string.Format`. Finally, `Split(@"\")` is not possible as Split does not accept a string (it does however accept a string[]) – StoriKnow Aug 28 '12 at 20:43
0

I've seen so many variations of the same, why not put it into a function like:

string GetUserName()
{
    var currentName =  WindowsIdentity.GetCurrent()?.Name;
    if (string.IsNullOrEmpty(currentName)) return null;
    var nameSplit = currentName.Split(@"\");
    string name = (nameSplit.Length > 1)
                    ? $"{nameSplit[1]}@{nameSplit[0]}" : currentName;
    return name;
}
Matt
  • 25,467
  • 18
  • 120
  • 187
  • When will `currentName ` return `null` value? – el-musleh Aug 31 '22 at 12:22
  • Normally it will not, but if the function cannot obtain the name it might happen. And then the function GetUserName() does not break, but returns null. – Matt Sep 01 '22 at 06:44