Ordner Icons auslesen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Ordner Icons auslesen

    Schönen guten Abend,

    ich möchte das Icon eines Ordners in einer Picturebox anzeigen. Das funktioniert auch soweit mit diesem Code.

    VB.NET-Quellcode

    1. <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.[Unicode])>
    2. Public Structure SHFILEINFOW
    3. Public hIcon As IntPtr
    4. Public iIcon As Integer
    5. Public dwAttributes As Integer
    6. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
    7. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
    8. End Structure
    9. <DllImport("shell32.dll", EntryPoint:="SHGetFileInfoW")>
    10. Private Shared Function SHGetFileInfoW(<InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFOW, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer
    11. End Function
    12. <DllImport("user32.dll", EntryPoint:="DestroyIcon")>
    13. Private Shared Function DestroyIcon(ByVal hIcon As System.IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    14. End Function
    15. Private Function GetIcon(ByVal PathName As String) As Bitmap
    16. Dim RIcon As New SHFILEINFOW
    17. SHGetFileInfoW(PathName, 0, RIcon, Marshal.SizeOf(RIcon), &H100 Or &H1)
    18. Dim FinalyImage As Bitmap = Icon.FromHandle(RIcon.hIcon).ToBitmap
    19. DestroyIcon(RIcon.hIcon)
    20. Return FinalyImage
    21. End Function​


    Nun zu meinem Problem. Wie kann ich jetzt noch zusätzliche Informationen abrufen. Z.b. in welcher Datei ist das Icon gespeichert und welchen Index hat es.

    Hoffe auf eure Hilfe.

    Grüße TM
    @Toolmaster Habich in meiner Snippetsammlung gefunden.
    Form mit Button, Label, PictureBox:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
    4. Shared Function PickIconDlg(ByVal owner As IntPtr, ByVal fileName As System.Text.StringBuilder, ByVal maxFile As Integer, ByRef iconIndex As Integer) As Integer
    5. End Function
    6. <DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
    7. Shared Function ExtractIconEx(ByVal szFileName As String, _
    8. ByVal nIconIndex As Integer, _
    9. ByVal phiconLarge() As IntPtr, _
    10. ByVal phiconSmall() As IntPtr, _
    11. ByVal nIcons As Integer) As Integer
    12. End Function
    13. <DllImport("user32.dll", EntryPoint:="DestroyIcon", SetLastError:=True)> _
    14. Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Integer
    15. End Function
    16. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    17. Dim iconfile As String = Environment.GetFolderPath(Environment.SpecialFolder.System) & "\shell32.dll"
    18. Dim sb As New System.Text.StringBuilder(iconfile, 500)
    19. Dim index As Integer
    20. Dim retval As Integer
    21. retval = PickIconDlg(Me.Handle, sb, sb.Capacity, index)
    22. If (retval = 1) Then
    23. Me.Label1.Text = index.ToString
    24. Dim icon = ExtractIconFromExe(iconfile, index, True)
    25. Me.PictureBox1.Image = icon.ToBitmap()
    26. End If
    27. End Sub
    28. Public Function ExtractIconFromExe(ByVal fileName As String, ByVal iconindex As Integer, ByVal large As Boolean) As Icon
    29. Dim hDummy As IntPtr() = New IntPtr(0) {IntPtr.Zero}
    30. Dim hIconEx As IntPtr() = New IntPtr(0) {IntPtr.Zero}
    31. Try
    32. Dim iconCount As Integer
    33. If (large) Then
    34. iconCount = ExtractIconEx(fileName, iconindex, hIconEx, hDummy, 1)
    35. Else
    36. iconCount = ExtractIconEx(fileName, iconindex, hDummy, hIconEx, 1)
    37. End If
    38. If (iconCount > 0 AndAlso Not hIconEx(0).Equals(IntPtr.Zero)) Then
    39. ' GET FIRST EXTRACTED ICON
    40. Dim extractedIcon As Icon = CType(Icon.FromHandle(hIconEx(0)).Clone(), Drawing.Icon)
    41. Return extractedIcon
    42. Else ' NO ICONS READ
    43. Return Nothing
    44. End If
    45. Catch ex As Exception
    46. ' EXTRACT ICON ERROR
    47. ' BUBBLE UP
    48. Throw New ApplicationException("Could not extract icon", ex)
    49. Finally
    50. 'RELEASE RESOURCES
    51. For Each ptr As IntPtr In hIconEx
    52. If (Not ptr.Equals(IntPtr.Zero)) Then
    53. DestroyIcon(ptr)
    54. End If
    55. Next ptr
    56. For Each ptr As IntPtr In hDummy
    57. If Not (ptr.Equals(IntPtr.Zero)) Then
    58. DestroyIcon(ptr)
    59. End If
    60. Next ptr
    61. End Try
    62. End Function
    63. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Toolmaster Bitte.
    Bist Du der Meinung, dass das System dem Ordner ein Icon per Index zuweist ohne eine explizite Quelle zu haben?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Toolmaster schrieb:

    die Quelldatei (Icondatei) und den Index
    Welche Information hast Du noch nicht bekommen?
    Nicht, dass Du Dich da iwie verrennst.
    Möglicherweise gibt es mehrere Icon-DLLs, die je nach Größe des Icons verwendet werden. Kläre das mal auf.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe keinen Schimmer worauf du hinaus willst. Mein Code:

    VB.NET-Quellcode

    1. ​Private Function GetIcon(ByVal PathName As String) As Bitmap
    2. Dim RIcon As New SHFILEINFOW
    3. SHGetFileInfoW(PathName, 0, RIcon, Marshal.SizeOf(RIcon), &H100 Or &H1)
    4. Dim FinalyImage As Bitmap = Icon.FromHandle(RIcon.hIcon).ToBitmap
    5. DestroyIcon(RIcon.hIcon)
    6. Return FinalyImage
    7. End Function


    Den ich mit

    VB.NET-Quellcode

    1. Picturebox1.Image = ​GetIcon(C:\AdwCleaner)
    aufrufe liefert mir das Icon des Ordners. Egal in welcher Datei es gespeichert ist. Nur möchte ich eben genau das wissen. Von wo kommt das Icon.
    Einfacher kann ich es leider nicht mehr beschreiben. Sorry
    @Toolmaster Ich weiß nicht, wo Dein Problem liegt.
    Ich habe Dir einen Code geliefert, wo Systemicons ausgelesen werden können.
    Ob das exakt diese DLL ist (insbesondere wegen der Größe der Icons) weiß ich nicht, jedenfalls wird solch Ordnericon bei mir gelistet.
    Was ganz genau missfällt Dir an meiner Lösung?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Kurze Zwischenfrage @Toolmaster: Wie sieht denn das AdwCleaner-Ordnersymbol aus? Wie jeder andere Ordner auch? Dann ist es das Default-Ordner-Icon, welches eben in der Standardwindowssymboldatei hinterlegt ist, die RfG erwähnte. Dann brauchst Du eigentlich nur immer in jener Datei zu schauen. Denn Windows schaut normalerweise nicht nach irgendeinem Symbol, sondern verwendet eigentlich immer das eine:

    modifiziert es aber - wie auch immer - abhängig vom Ordnerinhalt.
    Wenn das AdwCleaner-Bild aber anders aussieht, lad mal bitte einen entsprechenden Screenshot hoch. Bilder kannst Du forenintern über [+ Erweiterte Antwort] -> _|Dateianhänge|_ -> [Hochladen] posten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Toolmaster Die eigentliche Fragestellung in Post #1 wurde perfekt beantrwortet.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!