Results 1 to 10 of 10

Thread: Updating Processes

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2009
    Posts
    13

    Updating Processes

    I've been looking at different ways of getting processes and updating them. I first looked at WMI and then decided to just use the Process Class.

    I found some code on another web site that shows how to update processes in a ListBox. Ideally, I'd like to use a listview.

    I've been trying for a couple of days on how to get this to work, but I've come up short. If you all can help me understand the process, I'd appreciate it.

    The original poster created a class first and then updated the processes within a timer I believe. I tested it with a listbox, and it works well. The process is surprisingly smooth.

    vb.net Code:
    1. Class proc
    2.         Public name As String
    3.         Public Id As Integer
    4.         Overrides Function ToString() As String
    5.             Return name
    6.         End Function
    7.     End Class

    vb .net Code:
    1. Private Sub UpdateProcesses()
    2.         proclist = Process.GetProcesses()
    3.         For Each p As Process In proclist
    4.             Dim p2 As New proc
    5.             p2.name = p.ProcessName
    6.             p2.Id = p.Id
    7.             Dim add As Boolean = True
    8.             For Each pr As proc In ListBox1.Items
    9.                 If (pr.Id = p.Id) Then
    10.                     add = False
    11.                 End If
    12.             Next
    13.             If add Then
    14.                 ListBox1.Items.Add(p2)
    15.             End If
    16.         Next
    17.         Dim l As New ListBox()
    18.         Dim b As New ListBox.ObjectCollection(l, ListBox1.Items)
    19.         For Each p As proc In b
    20.             Try
    21.                 Dim p2 As Process = Process.GetProcessById(p.Id)
    22.                 Dim s = p2.ProcessName
    23.             Catch ex As Exception
    24.                 ListBox1.Items.Remove(p)
    25.             End Try
    26.         Next
    27.     End Sub

    Thanks

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Updating Processes

    So basically your only problem is adding information to a ListView, right? You've already got all the information.

    First you would need to set the View property of the ListView to details, then add the columns in the designer. At run time, to add an item to the ListView you first create a ListViewItem with the text for the first column, then add ListViewSubItems to that for the other columns, then add the item to the control's Items collection.

    I have to say, using exceptions to prompt removal of items is poor form, and there's really no need anyway. You're getting all the process each time anyway. You should simply clear the Items collection of the control each time and completely repopulate it. There would have to be a lot of processes for you to notice any lag and it would probably still perform better than throwing exceptions anyway.

    E.g.
    Code:
    Me.ListView1.BeginUpdate()
    Me.ListView1.Items.Clear()
    
    Dim item As ListViewItem
    
    For Each p In Process.GetProcesses()
        item = New ListViewItem(p.Id.ToString())
        item.SubItems.Add(p.ProcessName)
        Me.ListView1.Items.Add(item)
    Next
    
    Me.ListView1.EndUpdate()
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    New Member
    Join Date
    Oct 2009
    Posts
    13

    Re: Updating Processes

    I guess the thing I'm having a hard time figuring out is the ObjectCollection he declares with the variable, b.

    What would be the counterpart for a listview?

    I tried redoing the code to something like this:
    vb Code:
    1. proclist = Process.GetProcesses()
    2.         For Each p As Process In proclist
    3.             Dim p2 As New proc
    4.             p2.name = p.ProcessName
    5.             p2.Id = p.Id
    6.             Dim add As Boolean = True
    7.             For Each pr As proc In ListView1.Items
    8.                 If (pr.Id = p.Id) Then
    9.                     add = False
    10.                 End If
    11.             Next
    12.             If add Then
    13.                 Dim lvi As ListViewItem = New ListViewItem
    14.                 lvi.Text = (p2.ToString)
    15.                 ListView1.Items.Add(lvi)
    16.             End If
    17.         Next
    18.         Dim l As New Listview()
    19.         Dim b As New ListView.ListViewItemCollection(l, [B]ListView1.Items[/B])
    20.         For Each p As proc In b
    21.             Try
    22.                 Dim p2 As Process = Process.GetProcessById(p.Id)
    23.                 Dim s = p2.ProcessName
    24.             Catch ex As Exception
    25.                 ListView1.Items.Remove([B]p[/B])
    26.             End Try
    27.         Next

    The bold lines are the two issues throwing exceptions.

    The first error states: Too many arguments to 'Public Sub New(owner as System.Windows.Forms.Listview)'.

    Second error: Value of type 'WindowsApplication1.proc' cannot be converted to 'System.Windows.Forms.ListviewItem'.

    The second error appeared after I changed the ListboxObjectCollection to ListViewItemCollection. So, I imagine after I fix that, it should resolve itself.

    I tired changing the first error to an ListViewItemCollection instead of .Items, but that didn't work.

    Since the error states that there are too many arguments, I'd think that it could only have one variable passed to it since two seems like an "overload".

    I tried taking out the variable l but that didn't work. I didn't think it would because it seems that it would need that variable for the newly declared ListView, though I don't understand why.

    Also, my problem could be the ListViewItemCollection I changed from the ObjectCollection. It seemed like the appropriate counterpart, but I could be wrong. I was thinking that the ObjectCollection was a ListBox's way of getting a collection of items in the ListBox, so ListViewItemCollection seemed appropriate.

    Thanks
    Last edited by ForumDoe; Oct 9th, 2009 at 08:42 PM.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Updating Processes

    I've got to say, looking at that code, it makes no sense. It's creating a new ListBox each time. That's just crazy. You don't need to create a new control so you don't need to create a new ObjectCollection or the equivalent thereto. You've already got a ListView control and that's all you need. Just work with the Items collection of that ListView.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    New Member
    Join Date
    Oct 2009
    Posts
    13

    Re: Updating Processes

    I thought it seemed odd that a new control was being created. That's what I didn't understand why it was being done.

    I'll take it out, play around with it a little bit and see what I get.

  6. #6

    Thread Starter
    New Member
    Join Date
    Oct 2009
    Posts
    13

    Re: Updating Processes

    I modified the bottom half of the code to this:

    vb.net Code:
    1. For Each p As proc In ListView1.Items
    2.             Try
    3.                 Dim p2 As Process = Process.GetProcessById(p.Id)
    4.                 Dim s = p2.ProcessName
    5.             Catch ex As Exception
    6.                 ListView1.Items.Remove(p)
    7.             End Try
    8.         Next

    I get an error on the p variable when trying to remove it from the list.

    It says that proc cannot be converted to ListViewItem. I tried declaring p as a ListViewItem, but putting the code outside of the block hides the variable within an enclosing block. Putting it inside also does not work because the variable is already declared.

    How would I be able to remove the item from the list?

    Thanks

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Updating Processes

    Here's some fairly efficient code that will work with a ListView. I'm posting it twice; once for readability and once for copy-and-paste-ability:
    vb.net Code:
    1. Private processesByID As New Dictionary(Of Integer, Process)
    2.  
    3. Private Sub Form1_Load(ByVal sender As System.Object, _
    4.                        ByVal e As System.EventArgs) Handles MyBase.Load
    5.     Me.RefreshProcessList()
    6. End Sub
    7.  
    8. Private Sub Timer1_Tick(ByVal sender As System.Object, _
    9.                         ByVal e As System.EventArgs) Handles Timer1.Tick
    10.     Me.RefreshProcessList()
    11. End Sub
    12.  
    13. Private Sub RefreshProcessList()
    14.     'Create a dictionary of currently running processes keyed on their ID.
    15.     Dim currentProcessesByID = Process.GetProcesses().ToDictionary(Function(p) p.Id)
    16.  
    17.     'Remove processes that are no longer running.
    18.     For Each id In Me.processesByID.Keys.ToArray()
    19.         If Not currentProcessesByID.ContainsKey(id) Then
    20.             'This process is no longer running so destroy the Process object and remove it from the list.
    21.             Me.processesByID(id).Dispose()
    22.             Me.processesByID.Remove(id)
    23.         End If
    24.     Next
    25.  
    26.     'Add new processes.
    27.     For Each id In currentProcessesByID.Keys
    28.         If Me.processesByID.ContainsKey(id) Then
    29.             'This process is already in the list so destroy the duplicate.
    30.             currentProcessesByID(id).Dispose()
    31.         Else
    32.             'This is a new process so add it to the list.
    33.             Me.processesByID.Add(id, currentProcessesByID(id))
    34.         End If
    35.     Next
    36.  
    37.     'Update the list view.
    38.     Me.ListView1.BeginUpdate()
    39.     Me.ListView1.Items.Clear()
    40.  
    41.     'Add an item for each current process.
    42.     For Each id In Me.processesByID.Keys
    43.         Me.ListView1.Items.Add(id.ToString()).SubItems.Add(Me.processesByID(id).ProcessName)
    44.     Next
    45.  
    46.     Me.ListView1.EndUpdate()
    47. End Sub
    Code:
    Private processesByID As New Dictionary(Of Integer, Process)
    
    Private Sub Form1_Load(ByVal sender As System.Object, _
                           ByVal e As System.EventArgs) Handles MyBase.Load
        Me.RefreshProcessList()
    End Sub
    
    Private Sub Timer1_Tick(ByVal sender As System.Object, _
                            ByVal e As System.EventArgs) Handles Timer1.Tick
        Me.RefreshProcessList()
    End Sub
    
    Private Sub RefreshProcessList()
        'Create a dictionary of currently running processes keyed on their ID.
        Dim currentProcessesByID = Process.GetProcesses().ToDictionary(Function(p) p.Id)
    
        'Remove processes that are no longer running.
        For Each id In Me.processesByID.Keys.ToArray()
            If Not currentProcessesByID.ContainsKey(id) Then
                'This process is no longer running so destroy the Process object and remove it from the list.
                Me.processesByID(id).Dispose()
                Me.processesByID.Remove(id)
            End If
        Next
    
        'Add new processes.
        For Each id In currentProcessesByID.Keys
            If Me.processesByID.ContainsKey(id) Then
                'This process is already in the list so destroy the duplicate.
                currentProcessesByID(id).Dispose()
            Else
                'This is a new process so add it to the list.
                Me.processesByID.Add(id, currentProcessesByID(id))
            End If
        Next
    
        'Update the list view.
        Me.ListView1.BeginUpdate()
        Me.ListView1.Items.Clear()
    
        'Add an item for each current process.
        For Each id In Me.processesByID.Keys
            Me.ListView1.Items.Add(id.ToString()).SubItems.Add(Me.processesByID(id).ProcessName)
        Next
    
        Me.ListView1.EndUpdate()
    End Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8

    Thread Starter
    New Member
    Join Date
    Oct 2009
    Posts
    13

    Re: Updating Processes

    Thanks, jmcilhinney.

    Your example works, but there's a couple of problems. Although the flash I minimal, it still flashes when updates and flashes no matter if there is an update or not. Also when updating, the selected item loses focus and this is of course less than ideal.

    I'll look some more into it and see what I get, but do you know what can be done to resolve this?

    Thanks

  9. #9
    Wait... what? weirddemon's Avatar
    Join Date
    Jan 2009
    Location
    USA
    Posts
    3,826

    Re: Updating Processes

    Jmc, with the example you posted, couldn't you just add the items to the list to start with, and then add or delete them from the ListView instead of adding the list each time?

    Wouldn't that remove the flicker?

    It looks like you're adding and removing items to the dictionary. Then you're adding the whole dictionary to the ListView. From what I'm seeing, you're adding all of the processes each time. It's still removing and adding appropriate processes, but it's adding all of them, instead of just the ones needed.

    I could be wrong though
    CodeBank contributions: Process Manager, Temp File Cleaner

    Quote Originally Posted by SJWhiteley
    "game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Updating Processes

    Quote Originally Posted by weirddemon View Post
    Jmc, with the example you posted, couldn't you just add the items to the list to start with, and then add or delete them from the ListView instead of adding the list each time?

    Wouldn't that remove the flicker?

    It looks like you're adding and removing items to the dictionary. Then you're adding the whole dictionary to the ListView. From what I'm seeing, you're adding all of the processes each time. It's still removing and adding appropriate processes, but it's adding all of them, instead of just the ones needed.

    I could be wrong though
    You are correct that that is what my code is doing. Whether or not making the change you suggest would remove the flicker I don't know, but it may well do.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width