Get the name of a logged-on user within a Service [Solved]

Just starting out? Need help? Post your questions and find answers here.
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Get the name of a logged-on user within a Service [Solved]

Post by BigJack »

Hi all,
how can I get the name of a logged-on user when running my app as a service? (Windows XP Pro SP2)

To get the name I use this code, but it always returns SYSTEM as Username:

Code: Select all

;-======= Get User Name ===========
*mem = AllocateMemory(1000) 
buff.w = 1000 
GetUserName_(*mem, @buff) 
UserName$ = PeekS(*mem)
FreeMemory(*mem)
Last edited by BigJack on Mon Feb 04, 2008 11:12 am, edited 5 times in total.
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: How to get the name of a logged-on user....

Post by PB »

Code: Select all

a=999 : u$=Space(a) : GetUserName_(u$,@a) ; u$ = User name
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Post by BigJack »

Thanks, but this gives me the same result as the code I am using.

I am trying to get the user name from WITHIN an applicantion that runs as a system service...
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

what account does the service run under? If it's "local system" then it's returning the right result. Theres also a username env variable you could call.

echo %username%

will show you at dos prompt so you should be able to get this from the command that I can't remember off the top of my head that gets env vars
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Post by BigJack »

The service runs under "SYSTEM" and using the obove mentioned code, it returns SYSTEM as username.
I did some research and found out that the same problem occupied other programers (VB;C+) as well but couldn't find a solution.
How do I make an app run as LOCAL SERVICE instead of SYSTEM? What is the difference between the two?

NOTE:
One possible way to get it done is to get the account names from all running processes and disregard all which are run under system or local system.
The other ones must then be run under the user name. But how do I get the account name under which a process is started?
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Why not run it under some other account? Is this on a domain?

That way, when you need profiles set a certain way for proxy setting or the registry etc it's easy to log on as that users to modify them and know that the service account will get them.

This (assuming I'm understanding what you are saying) is not a bug or a problem. Can you not run your service as another account? often application services are run with a specially created service account, especially if it needs domain access.
The system account and the administrator account (Administrators group) have the same file privileges, but they have different functions. The system account is used by the operating system and by services that run under Windows. There are many services and processes within Windows that need the capability to log on internally (for example during a Windows installation). The system account was designed for that purpose; it is an internal account, does not show up in User Manager, cannot be added to any groups, and cannot have user rights assigned to it. On the other hand, the system account does show up on an NTFS volume in File Manager in the Permissions portion of the Security menu. By default, the system account is granted full control to all files on an NTFS volume. Here the system account has the same functional privileges as the administrator account.

NOTE: Granting either account Administrators group file permissions does not implicitly give permission to the system account. The system account's permissions can be removed from a file but it is not recommended.
Or :idea: do you mean that your service runs under the system account on a PC that so that when a user logs on you want to know who it is? Your service is independant of that though and is running when no one is logged on
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
DefaultUserName

maybe?
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
graves
Enthusiast
Enthusiast
Posts: 160
Joined: Wed Oct 03, 2007 2:38 pm
Location: To the deal with a pepper

Post by graves »

Maybe:

Code: Select all

    CPuser   = Space(#Max_Path)
    nSize.l  = #Max_Path
    GetUserName_(@CPuser,@nSize)
It's working here.
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Post by BigJack »

Or Idea do you mean that your service runs under the system account on a PC that so that when a user logs on you want to know who it is? Your service is independant of that though and is running when no one is logged on
Yes, that's what I want...

Thanks for the quick reply.
My app merely runs on a single pc with multi-user accounts.
Its purpose: Trying to get the name of the person that logs on.
Last edited by BigJack on Mon Feb 04, 2008 10:25 am, edited 1 time in total.
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Post by BigJack »

Thanks - problem solved !!!!

Your tip with the registry worked and returned the correct user name...
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
DefaultUserName
Thanks again for your help pdwyre; PB; Graves
:P
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

This is what pdwyer means:

Code: Select all

Define.s szBuf
szBuf = Space(#MAX_PATH)
GetEnvironmentVariable_(@"username", szBuf, #MAX_PATH)

Debug szBuf
I used the MAX_PATH const just because it's big enough to hold most usernames, use whatever you want though.

Just in case:
Return Value

If the function succeeds, the return value is the number of characters stored into the buffer pointed to by lpBuffer, not including the terminating null character.
If the specified environment variable name was not found in the environment block for the current process, the return value is zero.
If the buffer pointed to by lpBuffer is not large enough, the return value is the buffer size, in characters, required to hold the value string and its terminating null character.
EDIT: amm.. I think my browser didn't refresh when I hit F5... lots of answers there! sorry.

:lol: should I bash the keyboard and give up?
:?
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

pdwyer wrote:echo %username%
Better use

Code: Select all

Debug GetEnvironmentVariable("USERNAME")
PB 4.30

Code: Select all

onErrorGoto(?Fred)
BigJack
User
User
Posts: 76
Joined: Tue May 16, 2006 6:46 am
Location: Germany
Contact:

Post by BigJack »

Based on an article I discovered in a German forum, I came up with this solution: :D :D
Note:
Keep in mind, this is intended for applications that run as an nt service!!!
Most Windows APIs I have found return the username of the *calling thread*,
which when run as a system, is always "SYSTEM".

Code: Select all

;This code is meant for applications that run as a Windows Service 
;in order to find the name of a logged on user  or
;to check if any user has logged on to the system / multi-user account
;It assumes that the file "ntuser.dat" can be accessed ONLY if 
;a user has NOT logged on to the system
;and that it is located in the folder:  %SystemDrive%+"DocumentsFolder"+UserName
;which ought to return: C:\Documents\UserName\ntuser.dat

;Although there are easier ways to get this done when the app is run normally,
;however, when run a a SERVICE, most methods fail to provide the  correct user name.

;---------------------------------------------------------------------------
;Author: Mike Doran
;OS: Windows XP Pro SP2 /(Windows Vista not tested yet)
;Date: 2008 Feb 06 
;PureBasic 4.2
;===========================================================================

;------ Get path to check ntuser.dat ------
Test$ = GetRegKey(#HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList","ProfilesDirectory")
Test$ = StringField(Test$,2,"\")+"\"
Drive$ = GetEnvironmentVariable("SystemDrive")+"\"

Path$ = Drive$+Test$
Debug path$

;--- Get Name of last logged on User from registry ------
UserName$ = GetRegKey(#HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","DefaultUserName") 

;---- Check if ntuser.dat is present and accessible -------
If Username$  ;First check if ntuser.dat exist...
  Result = FileSize(Path$+UserName$+"\ntuser.dat")
  If result >0  ;File exists then continue  - if not, User has no account - Defaults to "System"
    ;Debug result
    Result = ReadFile(1, Path$+UserName$+"\ntuser.dat")
    If Result > 0 ;Check if ntuser.dat can be opened...
      UserName$ = "System"  ; if result = 0 then User is logged on = Cannot open file
    EndIf
  Else
    UserName$ = "System"  ;If it can be opened, no user has logged on
  EndIf  
Else
  UserName$ = "System"  
EndIf

Debug "Current Logged on User: "+UserName$
Greetings to all the folks back home in the States...
PB4.2 Windows XP SP3
Post Reply