|
-
Oct 9th, 2009, 02:00 PM
#1
Thread Starter
New Member
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:
Class proc
Public name As String
Public Id As Integer
Overrides Function ToString() As String
Return name
End Function
End Class
vb .net Code:
Private Sub UpdateProcesses()
proclist = Process.GetProcesses()
For Each p As Process In proclist
Dim p2 As New proc
p2.name = p.ProcessName
p2.Id = p.Id
Dim add As Boolean = True
For Each pr As proc In ListBox1.Items
If (pr.Id = p.Id) Then
add = False
End If
Next
If add Then
ListBox1.Items.Add(p2)
End If
Next
Dim l As New ListBox()
Dim b As New ListBox.ObjectCollection(l, ListBox1.Items)
For Each p As proc In b
Try
Dim p2 As Process = Process.GetProcessById(p.Id)
Dim s = p2.ProcessName
Catch ex As Exception
ListBox1.Items.Remove(p)
End Try
Next
End Sub
Thanks
-
Oct 9th, 2009, 08:05 PM
#2
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()
-
Oct 9th, 2009, 08:36 PM
#3
Thread Starter
New Member
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:
proclist = Process.GetProcesses() For Each p As Process In proclist Dim p2 As New proc p2.name = p.ProcessName p2.Id = p.Id Dim add As Boolean = True For Each pr As proc In ListView1.Items If (pr.Id = p.Id) Then add = False End If Next If add Then Dim lvi As ListViewItem = New ListViewItem lvi.Text = (p2.ToString) ListView1.Items.Add(lvi) End If Next Dim l As New Listview() Dim b As New ListView.ListViewItemCollection(l, [B]ListView1.Items[/B]) For Each p As proc In b Try Dim p2 As Process = Process.GetProcessById(p.Id) Dim s = p2.ProcessName Catch ex As Exception ListView1.Items.Remove([B]p[/B]) End Try 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.
-
Oct 9th, 2009, 09:43 PM
#4
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.
-
Oct 9th, 2009, 10:16 PM
#5
Thread Starter
New Member
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.
-
Oct 10th, 2009, 01:25 PM
#6
Thread Starter
New Member
Re: Updating Processes
I modified the bottom half of the code to this:
vb.net Code:
For Each p As proc In ListView1.Items
Try
Dim p2 As Process = Process.GetProcessById(p.Id)
Dim s = p2.ProcessName
Catch ex As Exception
ListView1.Items.Remove(p)
End Try
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
-
Oct 11th, 2009, 02:25 AM
#7
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:
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
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
-
Oct 13th, 2009, 09:18 PM
#8
Thread Starter
New Member
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
-
Oct 15th, 2009, 05:15 PM
#9
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
 Originally Posted by SJWhiteley
"game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....
-
Oct 15th, 2009, 05:21 PM
#10
Re: Updating Processes
 Originally Posted by weirddemon
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|