I am writing a VS extension which will need to communicate with a server and identify the user, and I figured that if possible, since this extension will be the only client connecting to the server, using Visual Studio's built-in support for Microsoft accounts would make more sense than implementing my own account management infrastructure.
At first, because of the variety of useful APIs available to a Visual Studio developer, one might think that getting info on the current user would be easy. However, there actually don't seem to be any obvious APIs that can be used to access accounts; I checked here and there weren't any related services listed (the "profile" services just allow you to read/write settings that are stored for the current user).
Does anyone know of a (relatively) simple way to access the Microsoft account from a Visual Studio extension?
EDIT
I tried Hadi Brais's suggestion, and at first it appeared to work (I successfully retrieved the information); however, each time, Visual Studio would crash about 30s afterward. I commented out the lines that interacted with the registry and replaced them with static values for the variables, and the crashes stopped. Clearly, accessing Visual Studio's registry keys was causing it to crash. I even tried using
statements and other safeguards, however there doesn't seem to be a way to safely access the Visual Studio registry keys from an extension. So does anyone know of any official APIs that can be used to retrieve this information without crashing Visual Studio?
For Visual Studio 2015 (Version 14.0), this is how to get information about the user that is currently signed in in Visual Studio. You need to add using Microsoft.Win32;
.
private static string GetUserEmailAddressVS14()
{
// It's a good practice to request explicit permission from
// the user that you want to use his email address and any
// other information. This enables the user to be in control
// of his/her privacy.
// Assuming permission is granted, we obtain the email address.
const string SubKey = "Software\\Microsoft\\VSCommon\\ConnectedUser\\IdeUser\\Cache";
const string EmailAddressKeyName = "EmailAddress";
const string UserNameKeyName = "DisplayName";
RegistryKey root = Registry.CurrentUser;
RegistryKey sk = root.OpenSubKey(SubKey);
if (sk == null)
{
// The user is currently not signed in.
return null;
}
else
{
// Get user email address.
return (string)sk.GetValue(EmailAddressKeyName);
// You can also get user name like this.
// return (string)sk.GetValue(UserNameKeyName);
}
}
There are now multiple versions of the IdeUser key. I've reimplemented the algorithm from the other answer this way:
public static string GetUserEmailAddressFromVisualStudioRegistry()
{
try
{
const string ConnectedUserSubKey = @"Software\Microsoft\VSCommon\ConnectedUser";
const string EmailAddressKeyName = "EmailAddress";
RegistryKey connectedUserSubKey = Registry.CurrentUser.OpenSubKey( ConnectedUserSubKey );
string[] subKeyNames = connectedUserSubKey?.GetSubKeyNames();
if ( subKeyNames == null || subKeyNames.Length == 0 )
{
return null;
}
int[] subKeysOrder = new int[subKeyNames.Length];
for ( int i = 0; i < subKeyNames.Length; i++ )
{
Match match = Regex.Match( subKeyNames[i], @"^IdeUser(?:V(?<version>\d+))?$" );
if ( !match.Success )
{
subKeysOrder[i] = -1;
continue;
}
string versionString = match.Groups["version"]?.Value;
if ( string.IsNullOrEmpty( versionString ) )
{
subKeysOrder[i] = 0;
}
else if ( !int.TryParse( versionString, out subKeysOrder[i] ) )
{
subKeysOrder[i] = -1;
}
}
Array.Sort( subKeysOrder, subKeyNames );
for ( int i = subKeyNames.Length - 1; i >= 0; i++ )
{
string cacheSubKeyName = $@"{subKeyNames[i]}\Cache";
RegistryKey cacheKey = connectedUserSubKey.OpenSubKey( cacheSubKeyName );
string emailAddress = cacheKey?.GetValue( EmailAddressKeyName ) as string;
if ( !string.IsNullOrWhiteSpace( emailAddress ) )
{
return emailAddress;
}
}
}
catch
{
// Handle exceptions here if it's wanted.
}
return null;
}
This algorithm tries all versions from the newest one and then all other siblings. It returns null in case of a failure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With