Results 1 to 6 of 6

Thread: Desktop item's names, paths, icons, and current size, with SysListView32

  1. #1

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    Post 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.

  2. #2

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    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.

  3. #3

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    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.

  4. #4

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    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.

  5. #5

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    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.

  6. #6

    Thread Starter
    Fanatic Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    581

    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
  •  



Click Here to Expand Forum to Full Width