Enumerating Processes & much more! Update - Real Time Updating
Looking over the Code Bank, I wasn't really able to find much on enumerating processes except for a WMI example. Since it seems like a lot of people are asking for such a thing, I decided to post an example I made up.
The example I've added is like a mini task manager. Below, I'll show you have to enumerate a list of processes and then add them to a ListView. My example also shows you how to obtain a bunch of different information about the processes and how to close them out as well.
There's a lot more features I'm going to add soon, so any suggestions, fixes, or code improvements are very much welcomed.
Now, on to enumerating processes...
There are a ton of different ways to go about this, so I'm just going to use the method I'm most familiar with.
First, I declare an array of processes and assign that array all of the running processes:
VB.NET Code:
Dim Processes() As Process = System.Diagnostics.Process.GetProcesses
Here I fully qualified the path with System.Diagnostics, but that isn't necessary if you've imported the namespace.
Next, I'll loop through that list and retrieve the appropriate information. Since I'm adding the info to a ListView, I declare a variable to hold the ListViewItem and then I add the variable to the ListView at the end.
VB.NET Code:
For Each proc As Process In Processes
Dim lvi As New ListViewItem
lvi.Text = proc.ProcessName
lvi.SubItems.Add(proc.Id.ToString)
ListView1.Items.Add(lvi)
Next proc
And that's it! It's a super easy "process"
You can download my Process Manager to get a better look at the code in action and see all of the information I've retrieved using the Process Class.
I really hate code commenting and since I made this pretty quick, I didn't do much of that. So, if there are any questions, ask away
My project obtains a ton of information about the processes such as: Name, PID, Memory Usage, Description, Modules, and much more!.
If you just want to use it, all you have to do is build the project and run the created executable. You can use the code in any way you like. All I ask is that you don't re-package it and call it your own
Process Manager:
Latest Update: Version 1.7
-Fixed an issue where you had to "re-click" the selected item in order to see a change in process priority
-Added an icon
-Added the ability to suspend and resume processes
Only problem I had with it is that the icons didnt match the processes in most cases, and also it would be nice if you could sort the list by clicking the column headers
Last edited by chris128; Jan 14th, 2010 at 05:23 AM.
Only problem I had with it is that the icons didnt match the processes in most cases, and also it would be nice if you could sort the list by clicking the column headers
Thanks, Chris for the feedback. I'll work on sorting to columns today.
As for the icons... that's a little odd. Did you debug the project or build it? For some reason I've yet to figure out, when you debug the app, half the icons are missing and are all jumbled up. But the build version seems to be working just fine.
Ah yes, I did just run it within VS rather than building it and then running the EXE. Not sure why on earth that would be happening I'll have a look at your code and see if I can see any reason why it would behave differently in the debug build (but I'll be surprised if I can)
Hi weirddemon , Nice job , I'm really learning alot from it.
I tested the program and I found the problem about icons that didnt match the
processes , that some files don't return an Icon and that cause a gab between the
ImageList and ListBox :
Try
Dim ico As Icon = Icon.ExtractAssociatedIcon(proc.MainModule.FileName)
Dim bmp As Bitmap = ico.ToBitmap()
imagesProcessIcons.Images.Add(bmp)
Catch ex As Exception
Dim SIco As Icon = Icon.ExtractAssociatedIcon("C:\windows\system32\cmd.exe")
Dim SBmp As Bitmap = SIco.ToBitmap
imagesProcessIcons.Images.Add(SBmp)
' MessageBox.Show(ex.Message)
End Try
So I used a random program - CMD - and I added it to the Exception handling
and it works now fine , of course you can choose another Icon to be the Default.
and handling the exception issues to fit your needs.
And after I tested "Kill" option , I found it cause another Icons issus , So I added
imagesProcessIcons.Images.Clear()
after
lvwProcess.Items.Clear()
To Clear the imagesProcessIcons and lvwProcess , And reload them again.
Last edited by Ashraf Alshahawy; Jan 14th, 2010 at 02:46 PM.
Some times when you make a step forward ...You can't get back. Be sure where you make your steps.
Hi weirddemon , Nice job , I'm really learning alot from it.
I tested the program and I found the problem about icons that didnt match the
processes , that some files don't return an Icon and that cause a gab between the
ImageList and ListBox :
Try
Dim ico As Icon = Icon.ExtractAssociatedIcon(proc.MainModule.FileName)
Dim bmp As Bitmap = ico.ToBitmap()
imagesProcessIcons.Images.Add(bmp)
Catch ex As Exception
Dim SIco As Icon = Icon.ExtractAssociatedIcon("C:\windows\system32\cmd.exe")
Dim SBmp As Bitmap = SIco.ToBitmap
imagesProcessIcons.Images.Add(SBmp)
' MessageBox.Show(ex.Message)
End Try
So I used a random program - CMD - and I added it to the Exception handling
and it works now fine , of course you can choose another Icon to be the Default.
and handling the exception issues to fit your needs.
I suppose that makes sense. I'll take your advice and change it up a little bit.
Thanks
Last edited by weirddemon; Jan 14th, 2010 at 02:36 PM.
I fixed your icons problem in the other thread, but I found another error by mistake so decided to post this here:
When you click the Properties button, the 'no items selected' check is done wrong. You are checking if SelectedItems is nothing, which it will never be. If there are no items selected, it will be an empty collection, so you need to check if it's Count (or Length if it's an array, can't remember) is zero. Right now the program crashes when you click Properties without having a ListViewItem selected.
I added some modification at the code to raise the speed of adding the
processes , and option to Show or Hide the Processes' Icons , and avoiding
Processes-Icons dismatch as I mentioned before.
I fixed your icons problem in the other thread, but I found another error by mistake so decided to post this here:
When you click the Properties button, the 'no items selected' check is done wrong. You are checking if SelectedItems is nothing, which it will never be. If there are no items selected, it will be an empty collection, so you need to check if it's Count (or Length if it's an array, can't remember) is zero. Right now the program crashes when you click Properties without having a ListViewItem selected.
Thanks. I think I fixed the Properties button. I changed the "Is Nothing" to ".Count = 0".
I also changed the code you mentioned in my other post and it looks okay now.
I've added a couple of updates now and Process Manager is changing a bit
I've taken Chris' suggestion and added column reordering.
Before, Process Manager could only work with Option Strict Off because I had about 3 improper conversions. All of those have been fixed and Option Strict On is now being used.
In the first release of Process Explorer, after a process was killed, I reloaded the entire list. Now, I only remove the item from the ListView.
The final thing I've added is custom highlighting. I decided it was probably a good idea for the user to readily see which processes were services or started by the User. In the image above, User processes are highlighted in that light blue color and services are in a light pink.
The User can change the colors or just see the legend by going to: Tools | Preferences | and then selecting the Process Highlighting tab.
Any more suggestions or improvements are highly welcomed. Thanks again guys!
Looking good One little suggestion (which you might have already done) is to make the "Process Information" form more accessible - ie make it so that when you double click a process in the list it opens up the information window for that process, and possibly also have the information thing on a right click context menu on each process. When I first launched the program, I didnt even realise you could get more info on the processes, it was only when I noticed the information form in the solution files that I thought to take another look and found the button near the top of the app.
Ah sorry, I couldnt download the latest version at work to confirm
Now that I have had a better look at the source code, here are a few thoughts/questions. Dont take it the wrong way, I'm not saying there are loads of problems with it and its rubbish (although hopefully you are mature enough not to be offended by someone offering suggestions ) - these are just things that I thought you might want to take a look at to improve it:
1. Why are you converting the process Icon to a Bitmap when the ImageList can hold Icons as well? Instead of this:
Code:
Dim ico As Icon = Icon.ExtractAssociatedIcon(proc.MainModule.FileName)
If ico IsNot Nothing Then
Dim bmp As Bitmap = ico.ToBitmap()
imagesProcessIcons.Images.Add(bmp)
End If
you could just do this:
Code:
Dim ico As Icon = Icon.ExtractAssociatedIcon(proc.MainModule.FileName)
If ico IsNot Nothing Then
imagesProcessIcons.Images.Add(ico)
End If
If the reason you did it was because they look better quality when converted to bitmap, just change the ColorDepth property of the ImageList to Depth32bit rather than Depth8bit and then the Icon versions will look just as good as the Bitmap versions (at least they do on my PC anyway)
2. A lot of empty Catch blocks in the Try/Catch blocks - the thought of empty Catch blocks gives me nightmares Even if there is nothing you can do in the Catch block, I would say you should almost always log it somewhere, even if its just Debug.WriteLine that you use to show the information in the Immediate Window when it is run in the debugger.
3. The highlighting of services doesnt actually get all services because you are only checking for the LOCAL SERVICE and NETWORK SERVICE accounts, when in fact a lot of services run under the LOCAL SYSTEM account (also known as just SYSTEM). Also, services can be set to run under any user account you want, even your own normal logon username, so just checking the user account that a process is owned by isnt really a reliable way to determine if a process is a service or not
4. In the Preferences window, in the Process Highlighting tab, both of the labels say "User Processes" ... I'm assuming one of them is supposed to say Service Processes or something like that?
5. The picture box in the Process Information window never seems to have an image in it for me, even for processes where it has successfully shown the icon in the listview.
6. If you click the Kill button before selecting any item in the listview, an unhandled exception is thrown because SelectedItems(0) does not equal anything. I would add a little check to the start of the kill routine that checks to make sure SelectedItems.Count > 0. Also setting the Kill and Information buttons to disabled when the app is first launched is probably a good idea.
Thanks for the feedback, Chris. I'm not offended at all. I realize that I don't know everything and there are going to be problems. So the suggestions and code fixes are extremely welcomed.
1. Why are you converting the process Icon to a Bitmap when the ImageList can hold Icons as well? Instead of this:
I was converting the image to a bitmap, because I was told that an ImageList could not hold Icons, only BitMaps.
2. A lot of empty Catch blocks in the Try/Catch blocks - the thought of empty Catch blocks gives me nightmares Even if there is nothing you can do in the Catch block, I would say you should almost always log it somewhere, even if its just Debug.WriteLine that you use to show the information in the Immediate Window when it is run in the debugger.
I too hate the empty blocks, so I am going to use Debug.WriteLine for now and create a method of logging the errors at a later point.
3. The highlighting of services doesnt actually get all services because you are only checking for the LOCAL SERVICE and NETWORK SERVICE accounts, when in fact a lot of services run under the LOCAL SYSTEM account (also known as just SYSTEM). Also, services can be set to run under any user account you want, even your own normal logon username, so just checking the user account that a process is owned by isnt really a reliable way to determine if a process is a service or not
I know that a service can be run under SYSTEM as well as the method I am using now. I'm trying to find a more reliable way of determining services.
4. In the Preferences window, in the Process Highlighting tab, both of the labels say "User Processes" ... I'm assuming one of them is supposed to say Service Processes or something like that?
Yeah. The latter one is supposed to say Services. I guess I overlooked it, but I'll fix it :P
5. The picture box in the Process Information window never seems to have an image in it for me, even for processes where it has successfully shown the icon in the listview.
I'm working on a way to get the large image of the process to go into the PictureBox
6. If you click the Kill button before selecting any item in the listview, an unhandled exception is thrown because SelectedItems(0) does not equal anything. I would add a little check to the start of the kill routine that checks to make sure SelectedItems.Count > 0. Also setting the Kill and Information buttons to disabled when the app is first launched is probably a good idea.
I've always had the buttons set as disabled by default, so this issue won't happen. So that's strange you're having that issue. I'll add an extra check in there just in case.
Thanks again. When I get a chance, I'll upload a fixed version
I've always had the buttons set as disabled by default, so this issue won't happen. So that's strange you're having that issue. I'll add an extra check in there just in case.
Maybe I selected a process which then enabled the buttons, then I clicked the refresh button which reloads all of the items and therefore clears the selected item in the listview but does not disable the buttons again.
I was converting the image to a bitmap, because I was told that an ImageList could not hold Icons, only BitMaps.
I tried it and on Windows 7 it seems to work fine, I would expect it does on other OS's as well but I have heard some things about differences in the way Icons can be used in the .NET framework when running on Vista/7 compared to XP
Thanks again, Chris. I've been wanting to make a project like this for a while and now that it's done, I knew there would be a lot of problems and things I needed to add. So all of the help you and others have given me is very much appreciated.
This update has added a couple of things and fixed some additional errors.
I took your advice, Chris, and changed how the icons were gathered. I am no longer converting the icons to bitmaps and I changed the ColorDepth property of the ImageList to Depth32Bit and it looks much better that way.
For now, I added Debug.WriteLine to the Try blocks, but I will create a method to log the errors at a later point.
I fixed the problem where the "Services Processes" label on the Preferences form was incorrect.
I fixed an issue where , after refreshing the process list, the Kill button would thrown an exception after being pressed. I added a check when the button is pressed (lvwProcess.SelectedItems.Count = 0). By default, the Kill and Properties buttons are disabled. So, when you press the refresh button, they go back to being disabled. This isn't entirely necessary since the check now exists within the Kill button, but I like it this way.
I also added the selected process' image to the Property form's picturebox. The only problem I'm having with this is that, after the image is added, it's stuck to the upper left corner of the box. I changed the layout property during design time and run time to Center, and it's still stuck up there. Anyone know why?
Before, you could access the properties of the process by selecting the item and then selecting the properties button or selecting properties from the ContextMenu Strip. Now you can also double click the process.
In this update, I've had to remove a couple of things and I've also added some.
The big thing I'm excited about is real time updating. Process Manager is now able to add and remove processes from the ListView automatically instead of the User manually select refresh.
For the most part, it seems to be working pretty well. There's a little bit of flickering at when starting it, but not too much. For some odd reason, it keeps the highlighting part when it first loads, but the User can't change the color of the highlighting. Well, they can it will affect all new processes added to the list, but it won't update the existing ones. It seems that I can't load the Process List sub manually anymore because of the RT updating. That seems odd, but I'm looking into it.
I've removed the services highlighting capability because it wasn't accurate and I'm working on a new way to obtain info.
I've added the ability to change the priority of the process. The user to choose from Idle to Highest and everything in between. For some reason that I don't know just yet, after the User changes the priority, you have to select a different process and then reselect that one to see the changes.
Hopefully I'll be able to fix those issues soon and implement other features I want.
Re: Enumerating Processes & much more! Update - Real Time Updating
Hi Weirddemon,
Great application! Really like it. You said to would like to hear suggestions:
1. When you right click on process, You have a submenu called process. That's a bit strange, of course this menu is about a process, I right clicked it! Kill should also be in this submenu the way it is now. Process -> Kill. So what I would do; remove the submenu or call it 'Edit' or something.
2. When you want to kill a process, it says "selected process". But I can't select more then one. I would only use the word selected when there is an option to select multiple processes. In this case I would use "this process". English is not my native language so I may be wrong on this one .
3. I couldn't find anything about what the blue colored processes mean in the application?
4. Trend Micro goes insane ands keeps blocking your application forever, when I start your application. Do you have infinite loop somewhere? Or when you an error occurs you try again forever?
Just some minor suggestion of not much importance but I thought you would like to know.
Good luck developing!
[EDIT]
And put & signs in front of submenu, menubuttons names. So users can use ALT- ?
Last edited by gonzalioz; Jan 18th, 2010 at 06:02 AM.
Re: Enumerating Processes & much more! Update - Real Time Updating
1. When you right click on process, You have a submenu called process. That's a bit strange, of course this menu is about a process, I right clicked it! Kill should also be in this submenu the way it is now. Process -> Kill. So what I would do; remove the submenu or call it 'Edit' or something.
When you click on tools or when you open the ContextMenu strip, you see that "Process" option. I call it that because the main items deal directly with the processes. The item that is in thee and future items are a sub-part of the processes.
2. When you want to kill a process, it says "selected process". But I can't select more then one. I would only use the word selected when there is an option to select multiple processes. In this case I would use "this process". English is not my native language so I may be wrong on this one .
When you talking about "selected process", are you referring to code? Either way,"selected" has nothing to do with pluralization. It seems means what is selected. If you want, you can change the multi-select property of the ListView. But I like having only one item selected ast a time.
3. I couldn't find anything about what the blue colored processes mean in the application?
Tools > Preferences > Process Highlighting
4. Trend Micro goes insane ands keeps blocking your application forever, when I start your application. Do you have infinite loop somewhere? Or when you an error occurs you try again forever?
I don't know why Trend Micro goes crazy. That's the first one I've seen. Since I work with Av/As applications day to day, I tested this app on many machines that had different Av/As applications. Among those are: MSSE, Kaspersky, NIS, WISE, and AVG.
I'll upload a new version today that has the Alt capabilities.
Updated
Last edited by weirddemon; Jan 18th, 2010 at 03:02 PM.
Re: Enumerating Processes & much more! Update - Real Time Updating
In version 1.7, you'll notice that I added Process Affinity.... At this time, it doesn't work and I didn't want to remove everything.
I added an icon and a couple other images and that made the project too large for the file size limit VBF has. So, I had to upload to a 3rd party site.
I put this version out a bit quicker than I wanted to because I really wanted to show off suspending processes
You can pretty much suspend any process. I haven't tested it on every process, but I did test a few. I would recommend not suspending any important processes, but you can do as you like
You can pause Process Manager, but unless you opened up a new instance of it, you'd have to close it out and restart it. Since I'm sure people will mistakenly do that, I added an extra check. When you attempt to pause process manager, you get a prompt that asks you if you're sure you'd like to pause it.
That's all I have so far. Hopefully I'll get Process Affinity working soon.
Re: Enumerating Processes & much more! Update - Real Time Updating
Originally Posted by chris128
Can you resume the process after you have paused it?
Yes. I wasn't sure how to determine if that process was paused. So, I kind of cheated. What I did was changed the backcolor of that ListViewItem to gray so that the User would know it's suspended. When the User selects a ListViewItem, I check if the ListViewItem's BackColor is Gray. If it is, I enable the Resume code and if not, I enable the Suspend.
The only potential problem is if the User changes the owner highlighting to gray. But, since that isn't working right now, I think I'm okay
I might have to come up with a better way later, but I could just prevent the user from using that shade of gray.
Re: Enumerating Processes & much more! Update - Real Time Updating
hey the link in the original post doesnt work anymore, it just says "invalid or deleted file" !
Also, not sure if you already found a way to do this but I finally got some code working that gets the parent process ID from a particular process - see my last post here: http://www.vbforums.com/showthread.php?t=599998
Re: Enumerating Processes & much more! Update - Real Time Updating
Originally Posted by minitech
Yeah, I got that too. Maybe it expired.
Right. It did the first time, then I replaced it. It did this time as well, but it should be okay now. I've replaced it with something a bit more permanent :P
Re: Enumerating Processes & much more! Update - Real Time Updating
Are you sure that your ico.GetHashCode().ToString() actually works for reusing icons? My version seems to make it a lot faster, you could try it in your next version:
(Import System.Drawing.Imaging, System.Security.Cryptography, System.Runtime.InteropServices.)
Code:
Private Function IconToString(ByVal ico As Icon) As String
Dim bmp As Bitmap = ico.ToBitmap()
Dim bd As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
Dim arr(bd.Width * bd.Height * 4 - 1) As Byte
Marshal.Copy(bd.Scan0, arr, 0, arr.Length)
bmp.UnlockBits(bd)
Dim hash256 As New SHA256Managed()
Dim b() As Byte = hash256.ComputeHash(arr)
Return System.Text.Encoding.ASCII.GetString(b)
End Function
Re: Enumerating Processes & much more! Update - Real Time Updating
Are you sure that your ico.GetHashCode().ToString() actually works for reusing icons? My version seems to make it a lot faster
Um... what do you mean exactly? Speed, I thought, was negligible, since it loads almost instantaneously. It does for all the machines I've tried it on.
Well, I have since disabled the WMI query since that seemed to have slowed it down tremendously.
Re: Enumerating Processes & much more! Update - Real Time Updating
I mean refreshes. I haven't done in-depth monitoring yet, but your Process Manager does similar things to the Task Manager Plus I tried making and your program seems to update a lot slower and make the rest of my computer slow, too.
P.S. It takes 3 seconds for the form to display on my computer, but it's a white screen for about 7.
Re: Enumerating Processes & much more! Update - Real Time Updating
Oh. I see.
Originally Posted by minitech
your program seems to update a lot slower
My timer updates every second and the changes reflect that time. However, you may be referring to how quickly it updates after it's been open for a while. In that case, I can understand.
I've tested it on a few machines at work, and it even crashed one PC after a few minutes of running. The issue is how much resources the application is consuming and not releasing. I posted about that here, but got no luck from testing and no responses.
Doing a quick test, this is how the memory consumption works out:
Start: 10, 000
30 Seconds: 18,000
1.5 Minutes: 25,000
After the 1 minute mark, it seemed to have leveled out. It would rise and then lower it's consumption, but stay pretty steady.
I removed the WMI query from the ListProcesses sub, which attribute to long load times and huge memory consumption.
P.S. It takes 3 seconds for the form to display on my computer, but it's a white screen for about 7.
If you comment-out the WMI query from the Sub, it should load marginally quicker.
Re: Enumerating Processes & much more! Update - Real Time Updating
Originally Posted by computerman
I have just downloaded it and I am coming across a problem with the clSystemInfo module. I am getting an error on this line:
Code:
Dim countTotalHandles As System.Diagnostics.PerformanceCounter = New System.Diagnostics.PerformanceCounter("Process", "Handles")
saying : Could not locate Performance Counter with specified category name 'Process', counter name 'Handles'.
I also get a similar error here:
Code:
Dim countCommitPeak As System.Diagnostics.PerformanceCounter = New System.Diagnostics.PerformanceCounter("Memory", "None")
saying : Could not locate Performance Counter with specified category name 'Memory', counter name 'None'.
Computerman
You'll probably have to work it out on your own, or comment out the code. I haven't worked on this project in a while and I probably won't pick it up for a while longer.
I haven't abandoned it though. I want to re-code it eventually and make it a bit more stable, but I've got too much on my plate at the moment.