Page 1 of 1

GetUserName and GetUserNameEx do not return the User Name

Posted: Mon Jul 30, 2012 10:59 am
by IdeasVacuum
GetUserName_() and GetUserNameEx_() do not really return the current logged-in User Name as MS suggest, unless the PC is only used by one person (i.e. there is only one log-in). If the PC has more than one User, you can see that GetUserName actually returns the 'registered owner' name. Is there another function that can do the job better?

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 11:08 am
by KJ67
Seems to work here;

Code: Select all

UName$=Space(#UNLEN)
l=#UNLEN
If GetUserName_(UName$, @l)
  Debug UName$
EndIf
I have three more accounts on this machine, and two of these on the same domain the last is local only.

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 11:13 am
by MachineCode
GetUserName_() has always worked fine for me with XP and Win 7 with multiple user accounts. Can you post steps required to reproduce your problem? Thanks.

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 11:37 am
by IdeasVacuum
This is the code I am using:

Code: Select all

Procedure.s GetUsrName()
;----------------------

      Protected sUsrName.s 
      Protected size.i = (#UNLEN + 1) ;Max chars for Windows User Name (256) + null char

             sUsrName = Space(size)

      If Not GetUserName_(@sUsrName,@size)
                sUsrName = "Name not verified"
      EndIf

      ProcedureReturn sUsrName

EndProcedure
GetUserNameEx is essentially the same but prefixes the User name with the Computer name.

I have tested this code on WinXP32bit and Win7 64bit.

Edit:
There might arise some situations when you need to have this information through a Windows service. If we use traditional API functions like GetUserName or GetUserNameEx, they simply return the user name of the process account under which that Windows service is running. It is the SYSTEM account in most cases. The above mentioned API functions always return SYSTEM as the currently logged in user.
Retrieving Logged In User Name using a Windows Service

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 1:32 pm
by STARGĂ…TE

Code: Select all

Debug GetEnvironmentVariable("USERNAME")

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 3:41 pm
by jpd
Hi IdeasVacuum,

this post on German forum can probably help you..
http://www.purebasic.fr/german/viewtopi ... 17#p276417
with this code you can retrieve the right logged-on user equal in which context this running.

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 5:55 pm
by IdeasVacuum
Thanks jpd, that does look very interesting. :mrgreen:

Although I won't be using the UserNametoStringSID() procedure, note that it crashes on FreeMemory(*sid).

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Mon Jul 30, 2012 6:13 pm
by IdeasVacuum
aaaaaaaaah - same result as GetUserNameEx() :cry: compiled as 32bit exe, run on Win7 64bit.

I tried GetEnvironmentVariable("USERNAME") before (and again now), no dice :(

A quick Google shows this up as a typical MS 'sloppy' issue.

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Tue Jul 31, 2012 2:58 pm
by jpd
Hi,

I'm not really sure that I have right understand your purpose

you running this program on standalone machine ?
you running the program with system account?


with GetUserName:
ex. on computer in a workgroup, if the computername is mycomp and username is admin then the returned username is "admin".
If running with system account the returned username is "system"

with GetUserNameEx:
ex. on computer in a workgroup, if the computername is mycomp and username is admin then returned username is
"mycomp\admin".
If running with system accout the returned username is "system"

With WTSQuerySessionInformation:
ex. on computer in a workgroup, if the computername is mycomp and username is admin then the returned username is
"admin", with system accout return admin

you can set the param to #true

the the name returned is
mycomp\admin in both cases.


here the new example.

Code: Select all

; coded by jpd, july 2012
EnableExplicit

#WTS_CURRENT_SERVER_HANDLE = 0
#WTS_CURRENT_SESSION = -1

Enumeration ;WTS_INFO_CLASS
  #WTSInitialProgram=0
  #WTSApplicationName
  #WTSWorkingDirectory
  #WTSOEMId
  #WTSSessionId
  #WTSUserName
  #WTSWinStationName
  #WTSDomainName
  #WTSConnectState
  #WTSClientBuildNumber
  #wtsclientname
  #WTSClientDirectory
  #WTSClientProductId
  #WTSClientHardwareId
  #WTSClientAddress
  #WTSClientDisplay
  #WTSClientProtocolType
EndEnumeration

Prototype WTSQuerySessionInformation(hServer.l,SessionId.l,WtsInfoClass.l,ppBuffer.l,pBytesReturned.l)
Global  WTSQuerySessionInformation.WTSQuerySessionInformation
Prototype WTSFreeMemory(lpBuffer.l)
Global  WTSFreeMemory.WTSFreeMemory

Procedure LoadWTSAPI() 
  Protected Result 
  
  Result = OpenLibrary(#PB_Any, "wtsapi32.dll") 
  If Result 
    
    WTSFreeMemory=GetFunction(Result, "WTSFreeMemory")
    CompilerIf #PB_Compiler_Unicode
      WTSQuerySessionInformation = GetFunction(Result, "WTSQuerySessionInformationW") 
    CompilerElse
      WTSQuerySessionInformation = GetFunction(Result, "WTSQuerySessionInformationA") 
    CompilerEndIf
    
    If WTSQuerySessionInformation = 0 
      CloseLibrary(Result) 
      Result = 0 
    EndIf      
  EndIf 
  
  ProcedureReturn Result 
  
EndProcedure 


Procedure.s CurrentSessionUserName(domain.b=#False)
  
  Protected pBytesReturnedaddress.l
  Protected UnameLength
  Protected Username.s
  Protected DomainName.s
  Protected libWTS
  Protected *username, *domainname
  Protected WTSQuery
  libWTS=LoadWTSAPI()
  If libWTS
    
    *username=AllocateMemory(256)
    
    WTSQuery= WTSQuerySessionInformation(#WTS_CURRENT_SERVER_HANDLE,#WTS_CURRENT_SESSION , #WTSUserName ,@*Username, @pBytesReturnedaddress)
    UnameLength=MemoryStringLength(*Username)
    Username=PeekS(*Username,UnameLength)
    WTSFreeMemory(*Username)
    If domain
      *domainname=AllocateMemory(256)
      WTSQuery= WTSQuerySessionInformation(#WTS_CURRENT_SERVER_HANDLE,#WTS_CURRENT_SESSION , #WTSDomainName,@*domainname, @pBytesReturnedaddress)
      UnameLength=MemoryStringLength(*domainname)
      DomainName=PeekS(*domainname,UnameLength)
      WTSFreeMemory(*domainname)
    EndIf
    
    CloseLibrary(libWTS)
  EndIf
  
  If Len(DomainName) > 0 And domain = #True
    ProcedureReturn DomainName+"\"+Username 
  Else
    ProcedureReturn Username
  EndIf
  
EndProcedure

Debug CurrentSessionUserName()

I'm not know what the return value if more as 1 user logged in and this is running with system right.

Sorry for my English, hope my comments are readable.

Re: GetUserName and GetUserNameEx do not return the User Nam

Posted: Tue Jul 31, 2012 3:10 pm
by IdeasVacuum
Thanks for getting back to me jpd. In fact, it is nearly impossible to correctly return the logged-in and currently active User Name 100% of the time, especially if the PC manufacturer has 'customized' the OS. - MS admit this fact when you read between the lines of numerous kb articles. I have decided not to worry about it, since the correct Name will be returned most of the time. When the correct Name is not returned, the User can manually enter it.