I was looking for a piece of code to show all users logged on to my system. What I mean by that is: only 1 person is ever truly logged in at my house, but there are sometimes other users "logged in" with programs running under their account. This is due to the "Fast Switching", "Switch User", feature of Windows. I found almost nothing, except for one idea that if you can find the owners of all "explorer.exe" processes running, then you will know who is "logged in". The .Net framework cannot do this alone, as far as I can tell. So I had to move on to WMI. WMI is awesome and powerful, but it seems to me that it can get quite confusing sometimes. Fortunately, I was able to combine a couple small pieces of WMI code that get the job done, and return a String Array with all users "logged in". I realize that this is not the most efficient way to do this, because I broke it down into a few different functions for illustration purposes. When you use this code, you may be able to condense it and make it your own. Also, I think the current user must have administrator privileges for this to work. I have tested it on Windows XP, and Windows 7.
Vb.Net Code for "Get Logged In Users":
Imports System.Management 'Required for WMI Code
'1) Get Explorer.exe handles...
Function GetExplorerHandles() As String()
'This returns a string array containing all handles for explorer.exe processes
Try
Dim sHandles(10) As String 'Temporary Buffer
Dim x As Integer = 0 'Count to assign values to array properly
Dim searcher As New ManagementObjectSearcher( _
"root\CIMV2", _
"SELECT * FROM Win32_Process WHERE Name = 'explorer.exe'")
For Each queryObj As ManagementObject In searcher.Get()
'Assign Handle to Array
sHandles(x) = queryObj("Handle")
'Increment Array
x = x + 1
Next
searcher.Dispose()
Return sHandles
Catch err As ManagementException
MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
Return Nothing
End Try
End Function
'2) Get Owners of Explorer.exe handles...
Function GetOwnerFromHandle(ByVal sHandle As String) As String
Try
Dim classInstance As New ManagementObject( _
"root\CIMV2", _
"Win32_Process.Handle='" & sHandle & "'", _
Nothing)
' no method [in] parameters to define
' Execute the method and obtain the return values.
Dim outParams As ManagementBaseObject = _
classInstance.InvokeMethod("GetOwner", Nothing, Nothing)
' Dispose of classInstance
classInstance.Dispose()
'Return owner of Handle
Return outParams("User")
Catch err As ManagementException
MessageBox.Show("An error occurred while trying to execute the WMI method: " & err.Message)
Return Nothing
End Try
End Function
'3) Save Owners to Array. (Logged in Users)
Function GetLoggedOnUsers() As String()
'Get All Handles for Explorer.exe processes running
Dim sHandles() As String = GetExplorerHandles()
Dim sOwners(10) As String '10 is only because I'm dodging "Not Set" error...
For i As Integer = 0 To sHandles.Length - 1
If sHandles(i) = "" Then Exit For
'Debug.WriteLine("Getting Owner From Handle: " & sHandles(i))
'Assign Owner to String Array
sOwners(i) = GetOwnerFromHandle(sHandles(i))
Next
'Return String Array with Logged In Users!
Return sOwners
End Function
'4) Display Logged On Users in ListBox
Sub DisplayLoggedOnUsers(ByVal lstUsers as ListBox)
'Get String Array of Users
Dim sOwners() As String = GetLoggedOnUsers()
'Clear List
lstUsers.Items.Clear()
'Display in List
For i As Integer = 0 To sOwners.Length - 1
If sOwners(i) = "" Then Exit For
lstUsers.Items.Add(sOwners(i))
Next
End Sub