Get current logged-in user

G

Guest

I have the following problem:

User A is logged in to a windows 2000 terminal. He runs an application which
runs under the credentials of a different user. If I try to see the current
user throught the application I can only see the user that started the
thread. How can I see the user that is logged in??

I tried the following code:

Private Function GetUser() As String
Dim strCurrentUser As String = ""
Dim moReturn As Management.ManagementObjectCollection
Dim moSearch As Management.ManagementObjectSearcher
Dim mo As Management.ManagementObject
'This scrolls through all the running processes on the PC to
determine who is running the "explorer.exe" process. It then returns the
username ready for comparison.
moSearch = New Management.ManagementObjectSearcher("Select * from
Win32_Process")
moReturn = moSearch.Get

For Each mo In moReturn
Dim arOwner(2) As String
mo.InvokeMethod("GetOwner", arOwner)
Dim strOut As String
strOut = String.Format("{0} Owner {1} Domain {2}", mo("Name"),
arOwner(0), arOwner(1))
MessageBox.Show(strOut)
If (mo("Name") = "explorer.exe") Then
strCurrentUser = String.Format("{0}", arOwner(0))
MessageBox.Show(strCurrentUser)
End If
Next
Return strCurrentUser
End Function

which works on my windows XP machine but when I try it on my windows 2000
terminal server (In workgroup mode) the owner of the explorer.exe proccess is
empty.


Any help.. PLEAAASSEEE....

Thanks in advance

Lucas
 
J

Jani Järvinen [MVP]

Lucas,
User A is logged in to a windows 2000 terminal. He runs an application
which
runs under the credentials of a different user. If I try to see the
current
user throught the application I can only see the user that started the
thread. How can I see the user that is logged in??

By "terminal", do you mean a physical PC, a user running cmd.exe (the "DOS
prompt"), or a server with Terminal Services and/or Citrix MetaFrame
running? Because Windows operating systems since NT4 can support multiple
users at the same time, there can be multiple explorer.exe's running at the
same time. Which of these users do you want? Also, does the application that
you refer to impersonate another user or not?

See this blog entry for discussion about the problem:
http://blogs.msdn.com/oldnewthing/archive/2006/08/22/712677.aspx

Now, my guess is that you are referring to the person physically attached to
the PC and his/her username, and in this case you could use the Terminal
Services (Win32) API functions WTSGetActiveConsoleSessionId and
WTSQuerySessionInformation:

http://msdn.microsoft.com/library/d...mserv/termserv/wtsquerysessioninformation.asp

First, you would call WTSGetActiveConsoleSessionId to get a session
identifier to the active console session (if any) and then given the session
ID, you would call WTSQuerySessionInformation with the WTSUserName
enumeration. This might be the information that you are looking for, though
I'm not exactly sure. Of course, you would need to use P/Invoke from .NET
code to get to these unmanaged API functions.

As for reference to others, to easily get the name of the user that is
running your application, you can use these properties in .NET:

- Environment.UserName
- System.Windows.Forms.SystemInformation.UserName
- or System.Security.Principal.WindowsIdentity.GetCurrent().Name

The last one returns the domain/computer name along with the username; the
two former ones only return the username.

Hope this helps!

--
Regards,

Mr. Jani Järvinen
C# MVP
Helsinki, Finland
(e-mail address removed)
http://www.saunalahti.fi/janij/
 
G

Guest

I am reffering to the person physically attached.

Its a windows 2000 terminal server with 3 users connected. 1 in front of the
server and another 2 with thinclients. Each user logs on with a different
login account. They all run an application that starts with an application
loader that launches that application as a different user (lets say
application_user). This application in turn starts another one where I need
to know the user name of the current session (The user that originally
launched the application)

I tried your suggestion but it is not easy for me to understand how to read
the buffer after I call the WTSUserName. I have searched everywhere and there
are no examples that use WTSUserName!!

The code I use is the following:

Imports System
Imports System.Runtime.InteropServices
Namespace TerminalServer

Friend Class Utilities

Public Enum WTS_INFO_CLASS
WTSInitialProgram
WTSApplicationName
WTSWorkingDirectory
WTSOEMId
WTSSessionId
WTSUserName
WTSWinStationName
WTSDomainName
WTSConnectState
WTSClientBuildNumber
WTSClientName
WTSClientDirectory
WTSClientProductId
WTSClientHardwareId
WTSClientAddress
WTSClientDisplay
WTSClientProtocolType
End Enum

<DllImport("Wtsapi32.dll")> _
Public Shared Function WTSQuerySessionInformation(ByVal hServer As
System.IntPtr, ByVal sessionId As Integer, ByVal wtsInfoClass As
WTS_INFO_CLASS, ByRef ppBuffer As System.IntPtr, ByRef pBytesReturned As
System.UInt32) As Boolean
End Function

<DllImport("Kernel32.dll")> _
Public Shared Function WTSGetActiveConsoleSessionId() As Integer
End Function

<DllImport("wtsapi32.dll")> _
Public Shared Sub WTSFreeMemory(ByVal memory As IntPtr)
End Sub


Public Const WTS_CURRENT_SERVER_HANDLE As Integer = -1

Friend Shared Function GetUserName() As String
Dim buffer As System.IntPtr = IntPtr.Zero
Dim bytesReturned As System.UInt32
Dim UserName As String


Dim sessionID As Integer = WTSGetActiveConsoleSessionId()

Try
Dim sessionInfo As Boolean =
WTSQuerySessionInformation(System.IntPtr.Zero, sessionID,
WTS_INFO_CLASS.WTSUserName, buffer, bytesReturned)
UserName = ' This is were I dont know what to do!
Catch
Return True
Finally
WTSFreeMemory(buffer)
buffer = IntPtr.Zero
End Try
Return UserName
End Function
End Class
End Namespace

Any help GREATLY appreciated.

Thanks

Lucas
 
G

Guest

Hi Lucas,

Just in case you didnt get this resolved I retrieve it like this:

Friend Shared Function GetUserName() As String

Dim buffer As System.IntPtr = IntPtr.Zero
Dim bytesReturned As UInt32

Try
WTSQuerySessionInformation(IntPtr.Zero, GetCurrentSession, _
WTSInfoClass.WTSUserName, buffer, bytesReturned)

Return Marshal.PtrToStringAuto(buffer)
Catch
Return Nothing
Finally
WTSFreeMemory(buffer)
buffer = IntPtr.Zero
End Try

End Function

I also use Marshal.ReadInt64(buffer) which return a long type to retrieve
UInt32 values (DWORD).

Regards,
Warren B
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top