|
-
Oct 30th, 2017, 08:15 PM
#1
Desktop item's names, paths, icons, and current size, with SysListView32
I've been racking my brains on this for over a week, but I can't figure how to get everything from the desktop listview with the code below which I found through Google. It gives me the number of desktop items, their icons xy coordinates, but wont list names. I haven't been able to get this to work, to include all item paths, their icons, and current size.
I know how to pull this information with GetFolderPath & GetFileSystemEntries, but I also need all desktop icon's xy coordinates, as well as an accurate item count, which is why I've been playing with this code. Could someone please help me out?
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const LVM_FIRST As UInteger = &H1000
Public Const LVM_GETITEMCOUNT As UInteger = LVM_FIRST + 4
Public Const LVM_GETITEMW As UInteger = LVM_FIRST + 75
Public Const LVM_GETITEMPOSITION As UInteger = LVM_FIRST + 16
Public Const PROCESS_VM_OPERATION As UInteger = &H8
Public Const PROCESS_VM_READ As UInteger = &H10
Public Const PROCESS_VM_WRITE As UInteger = &H20
Public Const MEM_COMMIT As UInteger = &H1000
Public Const MEM_RELEASE As UInteger = &H8000
Public Const MEM_RESERVE As UInteger = &H2000
Public Const PAGE_READWRITE As UInteger = 4
Public Const LVIF_TEXT As Integer = &H1
<DllImport("kernel32.dll")> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal dwFreeType As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindow(ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef dwProcessId As UInteger) As UInteger
End Function
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LVITEM
Public Mask As UInteger
Public Index As Integer
Public SubIndex As Integer
Public State As Integer
Public StateMask As IntPtr
Public Text As String
Public TextLength As Integer
Public ImageIndex As Integer
Public LParam As IntPtr
Public iItem As Integer
Public iSubItem As Integer
Public pszText As IntPtr
Public cchTextMax As Integer
Public iImage As Integer
Public iIndent As Integer
Public iGroupId As Integer
Public cColumns As Integer
Public puColumns As IntPtr
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As UInteger
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.Columns.Add("Name", 200)
ListView1.Columns.Add("Path", 150)
ListView1.Columns.Add("Location", 150)
ListView1.View = View.Details
ListView1.Font = New Font(New FontFamily("Arial"), 10, FontStyle.Regular)
'Get the handle of the desktop listview
Dim vHandle As IntPtr = FindWindow("Progman", "Program Manager")
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView")
'Get total count of the icons on the desktop
Dim vItemCount As Integer = SendMessage(vHandle, LVM_GETITEMCOUNT, 0, 0)
Label2.Text = vItemCount.ToString()
Dim vProcessId As UInteger
GetWindowThreadProcessId(vHandle, vProcessId)
Dim vProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, vProcessId)
Dim vPointer As IntPtr = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
Try
For j As Integer = 0 To vItemCount - 1
Dim vBuffer As Byte() = New Byte(255) {}
Dim vItem As LVITEM() = New LVITEM(0) {}
vItem(0).Mask = LVIF_TEXT
vItem(0).iItem = j
vItem(0).iSubItem = 0
vItem(0).cchTextMax = vBuffer.Length
vItem(0).pszText = IntPtr.op_Explicit(CInt(vPointer) + Marshal.SizeOf(GetType(LVITEM)))
Dim vNumberOfBytesRead As UInteger = 0
WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(GetType(LVITEM)), vNumberOfBytesRead)
'Get item's name
SendMessage(vHandle, LVM_GETITEMW, j, vPointer.ToInt32())
ReadProcessMemory(vProcess, vPointer + Marshal.SizeOf(GetType(LVITEM)), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, vNumberOfBytesRead)
Dim vText As String = Encoding.Unicode.GetString(vBuffer, 0, CInt(vNumberOfBytesRead))
'Get icon location
SendMessage(vHandle, LVM_GETITEMPOSITION, j, vPointer.ToInt32())
Dim vPoint As Point() = New Point(0) {}
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(GetType(Point)), vNumberOfBytesRead)
Dim IconLocation As String = vPoint(0).ToString()
Dim lvi As New ListViewItem
lvi.Text = vText
lvi.SubItems.Add("")
lvi.SubItems.Add(IconLocation)
'Insert an item into the ListView
ListView1.Items.Add(lvi)
Next
Finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE)
CloseHandle(vProcess)
End Try
End Sub
End Class
Last edited by Peter Porter; Oct 31st, 2017 at 10:05 PM.
-
Oct 31st, 2017, 10:13 PM
#2
Re: Desktop item's names, paths, icons, and current size, with SysListView32
If I can tweak the code above to get all desktop's Item's paths, I'll be able to pull the rest of their information easily.
Last edited by Peter Porter; Nov 1st, 2017 at 04:01 AM.
-
Nov 1st, 2017, 05:52 AM
#3
Re: Desktop item's names, paths, icons, and current size, with SysListView32
With a few changes to the code above, the vbuffer is still empty. Where am I going wrong?
Changes are highlighted in brown:
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const LVM_FIRST As UInteger = &H1000
Public Const LVM_GETITEMCOUNT As UInteger = LVM_FIRST + 4
Public Const LVM_GETITEMW As UInteger = LVM_FIRST + 75
Public Const LVM_GETITEMPOSITION As UInteger = LVM_FIRST + 16
Public Const PROCESS_VM_OPERATION As UInteger = &H8
Public Const PROCESS_VM_READ As UInteger = &H10
Public Const PROCESS_VM_WRITE As UInteger = &H20
Public Const MEM_COMMIT As UInteger = &H1000
Public Const MEM_RELEASE As UInteger = &H8000
Public Const MEM_RESERVE As UInteger = &H2000
Public Const PAGE_READWRITE As UInteger = 4
Public Const LVIF_TEXT As Integer = &H1
<DllImport("kernel32.dll")> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal dwFreeType As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindow(ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef dwProcessId As UInteger) As UInteger
End Function
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LVITEM
Public Mask As UInteger
Public Index As Integer
Public SubIndex As Integer
Public State As Integer
Public StateMask As IntPtr
Public Text As String
Public TextLength As Integer
Public ImageIndex As Integer
Public LParam As IntPtr
Public iItem As Integer
Public iSubItem As Integer
Public pszText As IntPtr
Public cchTextMax As Integer
Public iImage As Integer
Public iIndent As Integer
Public iGroupId As Integer
Public cColumns As Integer
Public puColumns As IntPtr
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As UInteger
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.Columns.Add("Name", 200)
ListView1.Columns.Add("Path", 150)
ListView1.Columns.Add("Location", 150)
ListView1.View = View.Details
ListView1.Font = New Font(New FontFamily("Arial"), 10, FontStyle.Regular)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Get the handle of the desktop listview
Dim vHandle As IntPtr = FindWindow("Progman", "Program Manager")
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView")
'Get total count of the icons on the desktop
Dim vItemCount As Integer = SendMessage(vHandle, LVM_GETITEMCOUNT, 0, 0)
Label2.Text = vItemCount.ToString()
Dim vText(vItemCount) As String
Dim vProcessId As UInteger
GetWindowThreadProcessId(vHandle, vProcessId)
Dim vProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, vProcessId)
Dim vPointer As IntPtr = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
Try
For j As Integer = 0 To vItemCount - 1
Dim vBuffer As Byte() = New Byte(255) {}
Dim vItem As LVITEM() = New LVITEM(0) {}
vItem(0).mask = LVIF_TEXT
vItem(0).iItem = j
vItem(0).iSubItem = 0
vItem(0).cchTextMax = vBuffer.Length
vItem(0).pszText = DirectCast(vPointer + Marshal.SizeOf(GetType(LVITEM)), IntPtr)
Dim vNumberOfBytesRead As UInteger = 0
WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(GetType(LVITEM)), vNumberOfBytesRead)
'Get item's name
SendMessage(vHandle, LVM_GETITEMW, j, vPointer.ToInt32())
ReadProcessMemory(vProcess, DirectCast(vPointer + Marshal.SizeOf(GetType(LVITEM)), IntPtr), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, vNumberOfBytesRead)
vText(j) = Encoding.Unicode.GetString(vBuffer, 0, CInt(vNumberOfBytesRead))
'Get icon location
SendMessage(vHandle, LVM_GETITEMPOSITION, j, vPointer.ToInt32())
Dim vPoint As Point() = New Point(0) {}
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(GetType(Point)), vNumberOfBytesRead)
Dim IconLocation As String = vPoint(0).ToString()
Dim lvi As New ListViewItem
lvi.Text = vText(j)
lvi.SubItems.Add("")
lvi.SubItems.Add(IconLocation)
'Insert an item into the ListView
Me.ListView1.Items.Add(lvi)
Next
Finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE)
CloseHandle(vProcess)
End Try
End Sub
End Class
Last edited by Peter Porter; Nov 1st, 2017 at 06:55 AM.
-
Nov 1st, 2017, 06:49 AM
#4
Re: Desktop item's names, paths, icons, and current size, with SysListView32
I've changed a few things back since this code needs to work at runtime (not at a push of a button).
I thought adding LVM_GETITEMTEXT would solve this, but the vbuffer is still empty. I'm lost.
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const LVM_FIRST As UInteger = &H1000
Public Const LVM_GETITEMCOUNT As UInteger = LVM_FIRST + 4
Public Const LVM_GETITEMW As UInteger = LVM_FIRST + 75
Public Const LVM_GETITEMPOSITION As UInteger = LVM_FIRST + 16
Public Const LVM_GETITEMTEXT = (LVM_FIRST + 45)
Public Const PROCESS_VM_OPERATION As UInteger = &H8
Public Const PROCESS_VM_READ As UInteger = &H10
Public Const PROCESS_VM_WRITE As UInteger = &H20
Public Const MEM_COMMIT As UInteger = &H1000
Public Const MEM_RELEASE As UInteger = &H8000
Public Const MEM_RESERVE As UInteger = &H2000
Public Const PAGE_READWRITE As UInteger = 4
Public Const LVIF_TEXT As Integer = &H1
<DllImport("kernel32.dll")> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal dwFreeType As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindow(ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef dwProcessId As UInteger) As UInteger
End Function
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LVITEM
Public Mask As UInteger
Public Index As Integer
Public SubIndex As Integer
Public State As Integer
Public StateMask As IntPtr
Public Text As String
Public TextLength As Integer
Public ImageIndex As Integer
Public LParam As IntPtr
Public iItem As Integer
Public iSubItem As Integer
Public pszText As IntPtr
Public cchTextMax As Integer
Public iImage As Integer
Public iIndent As Integer
Public iGroupId As Integer
Public cColumns As Integer
Public puColumns As IntPtr
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As UInteger
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.Columns.Add("Name", 200)
ListView1.Columns.Add("Path", 150)
ListView1.Columns.Add("Location", 150)
ListView1.View = View.Details
ListView1.Font = New Font(New FontFamily("Arial"), 10, FontStyle.Regular)
'Get the handle of the desktop listview
Dim vHandle As IntPtr = FindWindow("Progman", "Program Manager")
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView")
'Get total count of the icons on the desktop
Dim vItemCount As Integer = SendMessage(vHandle, LVM_GETITEMCOUNT, 0, 0)
Label2.Text = vItemCount.ToString()
Dim vText(vItemCount - 1) As String
Dim vProcessId As UInteger
GetWindowThreadProcessId(vHandle, vProcessId)
Dim vProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, vProcessId)
Dim vPointer As IntPtr = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
Try
For j As Integer = 0 To vItemCount - 1
Dim vBuffer As Byte() = New Byte(255) {}
Dim vItem As LVITEM() = New LVITEM(0) {}
vItem(0).Mask = LVIF_TEXT
vItem(0).iItem = j
vItem(0).iSubItem = 0
vItem(0).cchTextMax = vBuffer.Length
vItem(0).pszText = IntPtr.op_Explicit(CInt(vPointer) + Marshal.SizeOf(GetType(LVITEM)))
Dim vNumberOfBytesRead As UInteger = 0
WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(GetType(LVITEM)), vNumberOfBytesRead)
'Get item's name
SendMessage(vHandle, LVM_GETITEMTEXT, j, vPointer.ToInt32())
ReadProcessMemory(vProcess, vPointer + Marshal.SizeOf(GetType(LVITEM)), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, vNumberOfBytesRead)
vText(j) = Encoding.Unicode.GetString(vBuffer, 0, CInt(vNumberOfBytesRead))
'Get icon location
SendMessage(vHandle, LVM_GETITEMPOSITION, j, vPointer.ToInt32())
Dim vPoint As Point() = New Point(0) {}
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(GetType(Point)), vNumberOfBytesRead)
Dim IconLocation As String = vPoint(0).ToString()
Dim lvi As New ListViewItem
lvi.Text = vText(j)
lvi.SubItems.Add("")
lvi.SubItems.Add(IconLocation)
'Insert an item into the ListView
Me.ListView1.Items.Add(lvi)
Next
Finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE)
CloseHandle(vProcess)
End Try
End Sub
End Class
Last edited by Peter Porter; Nov 1st, 2017 at 06:53 AM.
-
Nov 1st, 2017, 04:23 PM
#5
Re: Desktop item's names, paths, icons, and current size, with SysListView32
I've tweaked the code again with what I found here under comments:
https://www.codeproject.com/Articles...ons-on-desktop
...but still nothing. It worked for someone else under C#.
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const LVM_FIRST As UInteger = &H1000
Public Const LVM_GETITEMCOUNT As UInteger = LVM_FIRST + 4
Public Const LVM_GETITEM = (LVM_FIRST + 5)
Public Const LVM_GETITEMW As UInteger = LVM_FIRST + 75
Public Const LVM_GETITEMPOSITION As UInteger = LVM_FIRST + 16
Public Const LVM_GETITEMTEXT = (LVM_FIRST + 45)
Public Const PROCESS_VM_OPERATION As UInteger = &H8
Public Const PROCESS_VM_READ As UInteger = &H10
Public Const PROCESS_VM_WRITE As UInteger = &H20
Public Const MEM_COMMIT As UInteger = &H1000
Public Const MEM_RELEASE As UInteger = &H8000
Public Const MEM_RESERVE As UInteger = &H2000
Public Const PAGE_READWRITE As UInteger = 4
Public Const LVIF_TEXT As Integer = &H1
<DllImport("kernel32.dll")> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal dwFreeType As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
End Function
<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindow(ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef dwProcessId As UInteger) As UInteger
End Function
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure LVITEM
Public Mask As UInteger
Public Index As Integer
Public SubIndex As Integer
Public State As Integer
Public StateMask As IntPtr
Public Text As String
Public TextLength As Integer
Public ImageIndex As Integer
Public LParam As IntPtr
Public iItem As Integer
Public iSubItem As Integer
Public pszText As IntPtr
Public cchTextMax As Integer
Public iImage As Integer
Public iIndent As Integer
Public iGroupId As Integer
Public cColumns As Integer
Public puColumns As IntPtr
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As UInteger
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.Columns.Add("Name", 200)
ListView1.Columns.Add("Path", 150)
ListView1.Columns.Add("Location", 150)
ListView1.View = View.Details
ListView1.Font = New Font(New FontFamily("Arial"), 10, FontStyle.Regular)
'Get the handle of the desktop listview
Dim vHandle As IntPtr = FindWindow("Progman", "Program Manager")
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView")
'Get total count of the icons on the desktop
Dim vItemCount As Integer = SendMessage(vHandle, LVM_GETITEMCOUNT, 0, 0)
Label2.Text = vItemCount.ToString()
Dim vText(vItemCount - 1) As String
Dim vProcessId As UInteger
GetWindowThreadProcessId(vHandle, vProcessId)
Dim vProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, vProcessId)
Dim vPointer As IntPtr = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
Dim itemIndex As Integer
Try
For j As Integer = 0 To vItemCount - 1
'Declare and populate the LVITEM structure.
Dim vItem As New LVITEM()
vItem.Mask = LVIF_TEXT
vItem.cchTextMax = 512
vItem.iItem = itemIndex
vItem.iSubItem = 0
'Memory for the actual item text.
vItem.pszText = vPointer
'Send the LVM_GETITEM message to fill the LVITEM structure
Dim ptrvItem As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vItem))
Marshal.StructureToPtr(vItem, ptrvItem, False)
'Write the lvi structure into the desktops process memory
Dim vNumberOfBytesRead As UInteger = 0
WriteProcessMemory(vProcess, vPointer, ptrvItem, Marshal.SizeOf(vItem), vNumberOfBytesRead)
Marshal.FreeHGlobal(ptrvItem)
'Get the item at itemIndex
SendMessage(vHandle, LVM_GETITEM, j, vPointer.ToInt32())
'Read item text from desktop process memory
Dim vBuffer As Byte() = New Byte(4095) {}
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), 4096, vNumberOfBytesRead)
'Bytes to string
Dim itemText As String = Encoding.Unicode.GetString(vBuffer).TrimEnd(New Char() {ControlChars.NullChar})
'Get icon location
SendMessage(vHandle, LVM_GETITEMPOSITION, j, vPointer.ToInt32())
Dim vPoint As Point() = New Point(0) {}
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(GetType(Point)), vNumberOfBytesRead)
Dim IconLocation As String = vPoint(0).ToString()
Dim lvi As New ListViewItem
lvi.Text = itemText
lvi.SubItems.Add("")
lvi.SubItems.Add(IconLocation)
'Insert an item into the ListView
Me.ListView1.Items.Add(lvi)
Next
Finally
If vPointer <> IntPtr.Zero Then
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE)
End If
CloseHandle(vProcess)
End Try
End Sub
End Class
Last edited by Peter Porter; Nov 1st, 2017 at 04:27 PM.
-
Nov 4th, 2017, 10:49 AM
#6
Re: Desktop item's names, paths, icons, and current size, with SysListView32
I'm gettin' close. Below Shell32 pulls all item names from SysListView32, including disabled and hidden items from the desktop. Just need to figure out how to incorporate this into the code in my first comment above to get only the names of all visible desktop items with their xy coordinates.
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const PROCESS_VM_OPERATION As UInteger = &H8
Public Const PROCESS_VM_READ As UInteger = &H10
Public Const PROCESS_VM_WRITE As UInteger = &H20
Public Const MEM_COMMIT As UInteger = &H1000
Public Const MEM_RELEASE As UInteger = &H8000
Public Const MEM_RESERVE As UInteger = &H2000
Public Const PAGE_READWRITE As UInteger = 4
<DllImport("user32.DLL")> _
Public Shared Function FindWindow(ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.DLL")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UInteger, ByVal flAllocationType As UInteger, ByVal flProtect As UInteger) As IntPtr
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Get the handle of the desktop listview
Dim vHandle As IntPtr = FindWindow("Progman", "Program Manager")
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView")
Dim vProcessId As UInteger
Dim vProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, vProcessId)
Dim vPointer As IntPtr = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
'Access SysListView32
Dim sh As New Shell32.Shell
Dim dsktp As Shell32.Folder = SH.NameSpace(vPointer.ToInt32)
'Loop through SysListView32 for each Item's Name
Dim sb As New StringBuilder
For Each Item As Shell32.FolderItem In dsktp.Items
sb.AppendLine(Item.Name)
Next Item
Label1.Text = sb.ToString
End Sub
End Class
Tags for this Thread
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
|