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