0

EDIT

I still can't assign the process the username of the session id that is associated with it.

This is the code i use to retrieve user details:

    Public Sub GetUsers()
    Using server As ITerminalServer = manager.GetRemoteServer(strHostName)
        server.Open()
        For Each session As ITerminalServicesSession In server.GetSessions()
            If Not String.IsNullOrEmpty(session.UserName) Then
                dictuser.Add(session.SessionId, New User(session.SessionId, session.UserName))
            End If
        Next
    End Using
End Sub

my user class is defined simply as:

Public Class User
Private _SessionID As Integer
Private _UserName As String

Sub New(ByVal SessionID As Integer, ByVal UserName As String)
    _SessionID = SessionID
    _UserName = UserName
End Sub

Public ReadOnly Property SessionID As String
    Get
        Return _SessionID
    End Get
End Property

Public ReadOnly Property UserName As String
    Get
        Return _UserName
    End Get
End Property
End Class

i have created a function in my process class:

Public Sub AddUserInfo(ByVal UserName As String)
    _UserName = UserName
End Sub
A Smith
  • 251
  • 2
  • 4
  • 10
  • You should indeed add 2 properties for pagefile and working memory set. You said it yourself:"Create a class which has all the data i want to collect" – Koen Jan 20 '12 at 21:56

1 Answers1

1

This replaces the process if a process with the same id is found in the dictionary and automatically adds a new process otherwise.

dictProcess(process.ProcessId) = process

EDIT (in response to your edited question):

I would change the name of the Processes class to Process, since it is not a collection, but is supposed to represent one process. You could change the constructor of the Process class to

Public Sub New(ByVal ProcessId As Integer, ByVal ProcessName As String, ByVal SessionId As Integer)            
    _ProcessId = ProcessId            
    _ProcessName = ProcessName            
    _SessionId = SessionId            
End Sub

Then add a method

Public Sub AddWmiInfo (ByVal PageFileUsage As Integer, ByVal WorkingSetSize As Integer)
    _PageFileUsage = PageFileUsage            
    _WorkingSetSize = WorkingSetSize            
End Sub

Alternatively, you could also make these properties read/write, however you get a better encapsulation like this.

Add the basic process information to the dictionary using Cassia. Note that ProcessId is declared as Integer and thus the check Not String.IsNullOrEmpty(process.ProcessId) makes no sense.

For Each process As ITerminalServicesProcess In server.GetProcesses()                       
    dictprocess.Add( _
      process.ProcessId, _
      New Process(process.ProcessId, process.ProcessName, process.SessionId))                       
Next

Finally, you would add the information from the WMI like this

Dim p As Process = Nothing
For Each wmiProcess In prowmi
    If dictprocess.TryGetValue(wmiProcess.ProcessID, p) Then
        p.AddWmiInfo(wmiProcess.PageFileUsage, wmiProcess.WorkingSetSize)
    End If
Next

TryGetValue returns a process in the variable p. The second parameter of TryGetValue is a ByRef parameter.


EDIt #2:

Your loop should read

Dim p As Process = Nothing
For Each user As User In dictuser.Values
    If dictprocess.TryGetValue(user.SessionID, p) Then
        p.AddUserInfo(user.UserName)
    End If
Next

However, if you are never accessing the user dictionary through the key (session id), then a list would be more appropriate than a dictionary.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • Thanks for the help, but im really struggling to get started. Do i want to populate dictprocess first or run the wmi query? also should i be storing the wmi query output to a separate dictionary? – A Smith Jan 21 '12 at 00:49
  • I am not sure what you are trying to achieve. If you want to be able to access process information through a process id without having to query the wmi each time, then a dictionary is ok. Populate the dictionay the first time you need the information. You also might want to update this information from time to time. Add the information that you need to the Process class. On the other hand, if want to query the wmi each time you need the information in order to get actual values, then a dictionay is useless. – Olivier Jacot-Descombes Jan 21 '12 at 17:21
  • Again, thank you for the reply. I have updated my question and hopefully it makes a bit more sense of what i am trying to achieve! :) – A Smith Jan 21 '12 at 23:48
  • I updated my answer. Hope this helps. The Cassia propject can be found here [http://code.google.com/p/cassia](http://code.google.com/p/cassia) – Olivier Jacot-Descombes Jan 22 '12 at 16:43
  • Thanks for the response, i have managed to get the records updating perfectly. however i tried to use your method for another issue i have. I have tried to update my answer to help explain myself again :/ – A Smith Jan 23 '12 at 12:24
  • Thanks for correcting my mistake. I have stepped through the code and it populates the correct information but fails to add the user information to the process dictionary. it seems to just skip p.AddUserInfo(user.UserName) – A Smith Jan 23 '12 at 15:18
  • Test if the sessionIds in the dictuser are ok. – Olivier Jacot-Descombes Jan 23 '12 at 15:54
  • I tested to make sure the sessionids are ok in dictusers and they seem fine. When stepping through the code it never assigns a value to 'p', which would explain why it look liked it was skipping the AddUserInfo part. Not too sure why 'p' is empty as all the other variables have the correct information in?? – A Smith Jan 26 '12 at 09:41
  • In my example I set `p = Nothing` because otherwise the compiler gives a warning that `p` is not initialized. However, you would have to assign a "real" process to `p`, of cause. – Olivier Jacot-Descombes Jan 26 '12 at 15:08
  • Would i want to be assigning a 'real' process i obtain from the wmi query? or should i be looking to assign it the process id from my process dictionary? – A Smith Jan 26 '12 at 15:21
  • Sorry, I was wrong with my last comment. Please forget it. `p` is retrieved from the dictionary, so the "real" process comes from `dictprocess.TryGetValue(..., p)`. However, the statement about the compiler warning is still true. – Olivier Jacot-Descombes Jan 26 '12 at 15:34