tags:

views:

253

answers:

4
  • I try to get the full-name of the current log-in user (Fullname, not username).

  • The following code C#, C++ works fine but on XP computers not connected to the Net, I get empty string as result if I run it ~20 minutes after login (It runs OK whithin the first ~20 minutes after login)

  • A Win32 API (GetUserNameEx) is used rather that PrincipalContext since it PrincipalContext may takes up to 15 seconds when working offline.

  • Any Help why am I getting an empty string as result though a user full name is specified???

- C# Code

    public static string CurrentUserFullName
    {
        get
        {
            const int EXTENDED_NAME_FORMAT_NAME_DISPLAY = 3;
            StringBuilder userName = new StringBuilder(256);
            uint length = (uint) userName.Capacity;
            string ret;

            if (GetUserNameEx(EXTENDED_NAME_FORMAT_NAME_DISPLAY, userName, ref length))
            {
                ret = userName.ToString();
            }
            else
            {
                int errorCode = Marshal.GetLastWin32Error();
                throw new Win32Exception("GetUserNameEx Failed. Error code - " + errorCode);
            }

            return ret;
        }
    }

    [DllImport("Secur32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool GetUserNameEx(int nameFormat, StringBuilder lpNameBuffer, ref uint lpnSize);

- Code in C++

#include "stdafx.h"
#include <windows.h>
#define SECURITY_WIN32
#include <Security.h>
#pragma comment( lib, "Secur32.lib" )

int _tmain(int argc, _TCHAR* argv[])
{
    char szName[100];
    ULONG nChars = sizeof( szName );

    if ( GetUserNameEx( NameDisplay, szName, &nChars ) )
    {
        printf( "Name: %s\n", szName);
    }
    else
    {
        printf( "Failed to GetUserNameEx\n" );      
        printf( "%d\n", GetLastError() );
    }
    return 0;
}
A: 

Try to use GetUserNameExA (for ASCII) instead of GetUserNameEx macro. Does it help? Print also the output of the program.

Iulian Şerbănoiu
I've just tried it. The same results of GetUserNameEx for the GetUserNameExA.I get error-code 1332 printed which means "No mapping between account names and security IDs was done". Hoever, there is a full-name specified for the current user and valid results are returned at the beginning ~20 minutes after login. It stops working for unknown reason (I searched for viruses, disabled the screen-saver and any other thing that might make problems in those 20 minutes...)
Nir
+1  A: 

The function GetUserNameEx with NameDisplay can't work in offline mode. Information which are accessible only if the computer is online. I recommend you to implement some cashing of information like full name or other which is accessible in online mode only. For example if the computer is online you can retrieve and save information like Full User Name. So you can have in some your config-file of in registry a mapping between users SID and it's full name. If you don't able give full name directly you can get the information from your cash.

Windows has a lot of different notification (like NotifyAddrChange) which you can use (if needed) to monitor change from online to offline mode and back.

Most information which you can get about current user session (also in offline mode) you can get from LsaGetLogonSessionData and WTSQuerySessionInformation API (GetUserNameEx you already know), but you will not find full user name inside.

If you do find a way to get full name of user in offline mode please post the information to me.

Oleg
The problem is that my station might be offline all the time.In C# you can easily get the Full user name (no matter if you station is connected to the net or not) usingUserPrincipal.Current.DisplayName(UserPrincipal namespace: System.DirectoryServices.AccountManagement.)The problem is that this call might takes 5-15 seconds on disconnected station which is too much for me (I can cache it for the first time, but still 10 seconds for the first call is too much)
Nir
@Nir: For me, UserPrincipal.Current.DisplayName throws a PrincipalServerDownException on a disconnected station.
Fantius
A: 

I'm curious: for a 'permamently offline' station, where (in the OS) is the user name stored? By browsing control panel Users, it looks like local user accounts have no place to store a 'NameDisplay', there's only a user name.

Where that data is stored for a non-connected node would be a mystery to me. If (in fact) the data is only stored with the domain controller, the only thing I can think of is to cache the information as mentioned earlier.

Gimble
A: 

So use the 1st one, check result and then invoke the 2nd via async delegate. Your app won't get any lag and full name is certainly not it's core feature - I hope :-)

ZXX