views:

78

answers:

4

I am editing a c# WinForm solution and I do not understand the code that gets the user account name. The code is shown below.

The application shows a customized form for each user account and the user account name is needed to get user-specific configuration values from an SQL database.

What happens, to the best I can tell, is the returned user name is correct for the first user account accessed, but after switching to a different user account, the returned user account name is not updated and the initial user account name continues to be returned.

#region "Function to retrieve LoggedIn user"
/// <summary>
/// "Function to retrieve LoggedIn user"
/// </summary>
/// <returns></returns>
private string GetLoggedInUserName()
{
    ManagementClass objManClass = new ManagementClass("Win32_Process");
    ManagementObjectCollection arrManObjects = objManClass.GetInstances();
    foreach (ManagementObject objMan in arrManObjects)
    {
        if (objMan["Name"].ToString().Trim().ToLower() == "explorer.exe")
        {
            string[] arrArgs = { "", "" };
            try
            {
                objMan.InvokeMethod("GetOwner", arrArgs);
                sUserName = arrArgs[0];
                break;
            }
            catch (Exception lExp)
            {
                BusinessObject.Logger.Logger.Log(lExp);
            }
        }
    }
    return sUserName;
}
#endregion

This application is to run on XP, Vista and 7.

My instinct is to just use something like...

string sUserName = Environment.UserName;

...but my knowledge of the Windows OS is poor and the people who wrote the original code are much smarter than me.

So my two questions are: (1) Why does this code appear to not update to the new user name when I change user accounts? (2) why use the 'explore.exe' method instead of simply using 'Environment.UserName'?

Also, two projects in my solution have a GetLoggedInUserName()method. One project runs in the background with a timer that calls the other project, and that project generates the user-customized form.

I have another related question about why the form fails to appear for all user accounts except the admin account that I will post as a separate question once I figure out this question.

+2  A: 

If you want the currently logged in user, use can use the WindowsIdentity object:

string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Fredrik Mörk
I have noticed that using any of these three returns the current user: System.Security.Principal.WindowsIdentity.GetCurrent().Name, Environment.UserName, and SystemInformation.UserName. But using the 'explorer.exe' method shown above returns only the initial user account but it doesn't update when changing accounts. I don't want to delete a method before figuring out how it works and why the original coders used it.
Frederick
@Frederick:I am not sure about `SystemInformation.UserName`, but in the case of `WindowsIdentity.GetCurrent` and `Environment.UserName`, they will return return the user running the program (so if you start the program using `runas`, it will return the user you are running as, not the one that is logged in in Windows). The difference between them is that `Environment.UserName` returns the user name without the domain.
Fredrik Mörk
+1  A: 

For the user name bit try ...

string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

Rob Lowther
Damn, beaten to the finish line!
Rob Lowther
A: 

You can also use simply

Environment.UserName

saurabh
A: 

The Explorer process is always running when you log onto a Windows box, so it will always be found. If you open Task Manager and view the processes you will see it, and the account that started it. It looks like a throw back to VBScript, although I'm sure that there is an easier way to it with that too.

There is no good reason to use WMI to get the current user account on a local machine over other simpler methods.

Dan Iveson