Was looking for how to do this tonight, and I remember seeing that Hassan made a similar post AGES ago with how to get the process icon of a specific process. So, I took a look at that and stripped all the useless shit that was in it, and built it up again with some easy to use functions that will get the icons for all running processes (where applicable)
The library works best with a listview as it was intended to be used in conjunction with the "SmallImageList" property of the control.
What does it do?
Retrieves the small icons of every process in the supplied "procList"
Here's a looksee:
How do I code this magnificent fucker?
Pretty simply really, the class itself handles most of the coding, so you don't really needa worry about too much below common sense.
Here's an example of using it to populate a ListView control.:
Step One: Download and extract the .dll
Step Two: Go to VB and reference the extracted Dll.
Step Three: Import the IconExtractor namespace.
Step Four, time to start coding (I'm assuming that you've already added a listview)
Right, firstly go to your listview properties and set the "View" property to "SmallIcon"
Now, back to coding.
First, the signature:
[highlight=vb.net]
Private Sub fillProcesses(ByVal lView As ListView)
End Sub
[/highlight]
All the rest of the code will go in there.
First order of business is to get the process list, you can do this with any filtering you want as long as you end up with an array of processes, for this example I'm just going to take processes which have a window.
[highlight=vb.net]
Dim procList As Process() = Process.GetProcesses.Where(Function(p As Process) Not String.IsNullOrEmpty(p.MainWindowTitle)).ToArray
[/highlight]
Now to create the image list and apply it to the listview
[highlight=vb.net]
Dim images As ImageList = icoExtractor.getProcessIcons(procList)
lView.SmallImageList = images
[/highlight]
And then last but not least, we loop through the processes in the process list, add them and their image to the listview and finish up
[highlight=vb.net]
For each p As Process In procList
Dim lvItem As New ListViewItem(p.ProcessName.PadRight(lView.Width \ 4, " "c)) 'create a new listviewitem (the PadRight is due to a bug in the listview control which will occasionally join consecutive items into a single line, leave the padding)
lvItem.ImageKey = p.ProcessName 'here we set the image that corresponds to this process
lView.Items.Add(lvItem)
Next
[/highlight]
It should now look something like this:
[highlight=vb.net]
Imports iExtractor
Public Class Form1
Private Sub fillProcesses(ByVal lView As ListView)
Dim procList As Process() = Process.GetProcesses.Where(Function(p As Process) Not String.IsNullOrEmpty(p.MainWindowTitle)).ToArray
Dim imgList As ImageList = icoExtractor.getProcessIcons(procList)
lView.SmallImageList = imgList
For Each p As Process In procList
Dim lvItem As New ListViewItem(p.ProcessName.PadRight(lView.Width \ 4, " "c))
lvItem.ImageKey = p.ProcessName
lView.Items.Add(lvItem)
Next
End Sub
End Class
[/highlight]
Then to call it:
[highlight=vb.net]
fillProcesses(ListView1)
[/highlight]
And that's all there is to it.
SOURCE CODE
For anyone interested in taking a look at the source of the library, here it is:
(Note, not all of this was coded by me, I did in fact modify pretty much every single line of code, but would never have known the process of getting the icons without looking at an example first.) I even commented the fuck out of it for you guys.
NOTE! You will need to manually reference System.Management, System.Windows.Forms and System.Drawing.
Private Declare Auto Function SHGetFileInfo Lib "shell32" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef newHandle As IntPtr, ByVal cbFileInfo As Integer, ByVal uFlagsn As Integer) As Integer
Private Structure icoInfo
Public iconPath As String 'self explanatory, path of the process (where to get the icon)
Public processName As String 'again, obvious, process name. herp derp.
Public Sub New(ByVal i As String, ByVal p As String)
Me.iconPath = i
Me.processName = p
End Sub
End Structure
Private Function getIcon(ByVal processPath As String) As Image
Dim icoHandle As IntPtr = IntPtr.Zero 'create the variable to hold the handle, will be passed ByRef to the API and the actual handle will result.
Dim flags As Integer = &H100 Or &H10 Or &H1 'set the flags, basically says it's an icon, it's a small icon and some file shit
SHGetFileInfo(processPath, 256, icoHandle, 0, flags) 'API call, will point to our icon.
Dim ico As Icon = Icon.FromHandle(icoHandle) 'extract the icon from the handle.
Return ico.ToBitmap 'return the icon.
End Function
Public Shared Function getProcessIcons(ByVal processList As Process()) As ImageList
Dim procNames As String() = processList.Select(Function(p As Process) p.ProcessName).ToArray 'get the names of the processes in the list
Dim output As New ImageList 'create the imagelist we'll return.
Dim tempExtractor As New icoExtractor 'create an instance of the icoExtractor class to access the private methods.
Dim pList As List(Of icoInfo) = tempExtractor.getPaths(procNames) 'get the icon paths of all the processes.
For Each p As icoInfo In pList 'loop through the iconInfo of each entry.
If Not output.Images.ContainsKey(p.processName) Then output.Images.Add(p.processName, tempExtractor.getIcon(p.iconPath)) 'check if the imagelist contains the key, if not add the icon to the list.
Next
Return output 'return the imagelist.
End Function
Private Function getPaths(ByVal procNames As String()) As List(Of icoInfo)
Dim pList As New List(Of icoInfo) 'the output variable.
Using searcher As New ManagementObjectSearcher("root\CIMV2", "select * from Win32_Process") 'query the root\CIMV2 path, with the select * from Win32_Process query, will return info on every process.
Using iterator As ManagementObjectCollection.ManagementObjectEnumera tor = searcher.Get.GetEnumerator 'get the Enumerator to step through each object that the query returned
While iterator.MoveNext 'while there is still more processes...
Dim name As String = IO.Path.GetFileNameWithoutExtension(iterator.Curre nt("name").ToString) 'use the IO.Path class to remove and extensions from the process name (.exe etc)
If procNames.Contains(name) AndAlso iterator.Current("ExecutablePath") IsNot Nothing Then 'if the original process list contains this process, and it has an executable path...
pList.Add(New icoInfo(iterator.Current("ExecutablePath").ToStrin g, name)) 'add it to the icoInfo list
End If
End While
End Using 'dispose the Enumerator
End Using 'dispose the ObjectSearcher
Return pList 'return the list of icoInfo.
End Function
End Class
[/highlight]
Add this to the programs I made that will never get released *hint hint*
Good tut
OMG!
JASON THANKS!
Originally Posted by Exquizyth
THANKSSSSSSS
Don't say it, press it !
guys look at this
Originally posted by Jason
Was looking for how to do this tonight, and I remember seeing that Hassan made a similar post AGES ago with how to get the process icon of a specific process.
That icon extracting source was almost the same :P
Originally Posted by techial2
guys look at this
That icon extracting source was almost the same :P
Ummm, okay let's compare shall we then hotshot?
"Hassan's" original code:
[highlight=vb.net]
Imports System
Imports System.Drawing
Imports System****ntime.InteropServices
Public Class ExtractIcon
Private Enum SHGFI
Flags
SmallIcon = &H1
LargeIcon = &H0
Icon = &H100
DisplayName = &H200
Typename = &H400
SysIconIndex = &H4000
UseFileAttributes = &H10
End Enum
Public Enum IconType
SmallIcon = True
LargeIcon = False
End Enum
StructLayout(LayoutKind.Sequential)
Private Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As Integer
MarshalAs(UnmanagedType.LPStr,SizeConst = 260)
Public szDisplayName As String
MarshalAs(UnmanagedType.LPStr,SizeConst = 80)
Public szTypeName As String
Public Sub New(ByVal B As Boolean)
hIcon = IntPtr.Zero
iIcon = 0
dwAttributes = 0
szDisplayName = vbNullString
szTypeName = vbNullString
End Sub
End Structure
Private Declare Auto Function SHGetFileInfo Lib "shell32" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlagsn As SHGFI) As Integer
Public Function GetIcon(ByVal Path As String, Optional ByVal Ico As IconType = True) As Icon
Dim info As New SHFILEINFO(True)
Dim cbSizeInfo As Integer = Marshal.SizeOf(info)
Dim flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
If Ico = True Then
flags += SHGFI.SmallIcon
Else
flags += SHGFI.LargeIcon
End If
SHGetFileInfo(Path, 256, info, cbSizeInfo, flags)
Return Icon.FromHandle(info.hIcon)
End Function
End Class
[/highlight]
Now...that looks really fucking similar doesn't it? Apart from the win32 process query (which i edited anyway..) and the actual API declaration (which....oh my god...is a windows API) Not a hell of a lot is even similar.
Sigh, I think you're just butthurt 'cos you got called a leecher in another thread.
Jason actually Hassan's code is shorter and smaller , but i see you improved , good job with it .
Originally Posted by $haDe$'$ Alt
Jason actually Hassan's code is shorter and smaller , but i see you improved , good job with it .
Hassan's code has another method I didn't include there, and only returns the icon of a single process.
And, if we're going to talk in lines of code, mine is shorter... I have a few blank lines between functions. If you actually look at the code there is a lot of unnecessary stuff going on the original (no need for the structure, just need an IntPtr as we don't give a damn about any other attributes...etc etc)
Dim procList As Process() = Process.GetProcesses.Where(Function(p As Process) Not String.IsNullOrEmpty(p.MainWindowTitle)).ToArray
if the process had no application running it will return an empty string
so it won't return all process icon's only the ones who have an application running
why did u do that? i'm sorry i'm newibe
Dim procList As Process() = Process.GetProcesses.Where(Function(p As Process) Not String.IsNullOrEmpty(p.MainWindowTitle)).ToArray
if the process had no application running it will return an empty string
so it won't return all process icon's only the ones who have an application running
why did u do that? i'm sorry i'm newibe
Umm..that was my personal code. Create your list of processes however you want. I just wanted to get the list of processes where the processes have a window. If you want every single process just do
Dim procList As Process() = Process.GetProcesses()
the .Where was just personal filtering, you are under no obligation to use it exactly as I posted.
Originally Posted by Jason
Umm..that was my personal code. Create your list of processes however you want. I just wanted to get the list of processes where the processes have a window. If you want every single process just do
Dim procList As Process() = Process.GetProcesses()
the .Where was just personal filtering, you are under no obligation to use it exactly as I posted.
yeah i know that i was just asking why did u make it only who have mainwindowtittle anyway thanks