65.9K
CodeProject 正在变化。 阅读更多。
Home

SharpCompress 使用 TreeView & ListView 示例

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2019 年 10 月 8 日

MIT

1分钟阅读

viewsIcon

8257

downloadIcon

348

本示例展示了如何使用 SharpCompress 库与 TreeView & ListView。

引言

在本示例中,我将向您展示如何使用 SharpCompress.dll 库从 .rar.zip 文件中获取目录到 TreeView,并将文件获取到 ListView

对于本示例,我使用 SplitContainer,左侧使用 TreeView,右侧使用 ListView

当您打开 .rar.zip 文件时,所有目录都将进入 TreeView ,当您从 TreeView 选择一个目录时,如果该目录包含文件,则所有文件都将进入 ListView (如下例所示)。

Image Example.

背景

这种方法可能适用于不同的库,但我尚未测试过。

Using the Code

首先将 SharpCompress.dll 导入到您的项目中,并使用 Imports ,如下例所示

#Region " Imports "

Option Explicit On
Imports System.IO
Imports System.Runtime.InteropServices
Imports SharpCompress.Archives
Imports SharpCompress.Common

#End Region

Form 类中,声明以下内容

Public Class Form1 : Inherits Form

#Region " Declares "

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Code Quality", _
       "IDE0069:Disposable fields should be disposed", Justification:="<Pending>")>
    Private WithEvents Archive As IArchive
    Private szArchivePath As String
    Private ReadOnly listViewItems As New List(Of ListViewItem)()
    Public listViewItem As ListViewItem
    Private ReadOnly _ImgListFileType As New List(Of String)() From {"Empty"}

#End Region

End Class

我创建了 Sub 过程以便于使用代码。表单应如下所示

#Region " Imports "
Option Explicit On
Imports System.IO
Imports System.Runtime.InteropServices
Imports SharpCompress.Archives
Imports SharpCompress.Common

#End Region

Public Class Form1 : Inherits Form

#Region " Declares "

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Code Quality", _
      "IDE0069:Disposable fields should be disposed", Justification:="<Pending>")>
    Private WithEvents Archive As IArchive
    Private szArchivePath As String
    Private ReadOnly listViewItems As New List(Of ListViewItem)()
    Public listViewItem As ListViewItem
    Private ReadOnly _ImgListFileType As New List(Of String)() From {"Empty"}

#End Region

#Region " GetFileType "
    ''' <summary>
    ''' Collecting file extension and avoiding duplicate. Example: .exe, .txt, .jpg, etc.
    ''' </summary>
    ''' <param name="GetFrom"></param>
    ''' <param name="SearchIn"></param>
    Private Sub GetFileType(ByVal GetFrom As String, SearchIn As List(Of String))
        If Not SearchIn.Contains(GetFrom) Then
            SearchIn.Add(GetFrom)
            SearchIn.Remove(String.Empty)
        End If
    End Sub
#End Region

#Region " List Icons "
    ''' <summary>
    ''' List icons for each file type.
    ''' </summary>
    Private Sub ListIcons()
        'Getting each file type from list "_ImgListFileType" List(Of String)
        For Each iFound In _ImgListFileType
            If Not iFound = Nothing Then
                'Avoid duplication of images.
                If Not ImgLargeListView.Images.ContainsKey(iFound) Then
                    'To avoid "Cross-thread operation not valid" 
                    'when using Background Worker or some Thread.
                    'Adding images using GetIcon Module
                    If InvokeRequired Then
                        Invoke(Sub() ImgListView.Images.Add(iFound, GetFileIcon_
                                     (iFound, IconSize.SHGFI_SMALLICON)))
                        Invoke(Sub() ImgLargeListView.Images.Add(iFound, GetFileIcon_
                                     (iFound, IconSize.SHGFI_LARGEICON)))
                    Else
                        ImgListView.Images.Add(iFound, GetFileIcon_
                                              (iFound, IconSize.SHGFI_SMALLICON))
                        ImgLargeListView.Images.Add(iFound, GetFileIcon_
                                                   (iFound, IconSize.SHGFI_LARGEICON))
                    End If
                End If
            End If
        Next iFound
    End Sub
#End Region

#Region " Close Archive "
    ''' <summary>
    ''' Closing the archive.
    ''' </summary>
    Private Sub CloseArchive()
        If Not (Archive Is Nothing) Then
            Archive.Dispose()
        End If
    End Sub
#End Region

#Region " Fill TreeView "
    ''' <summary>
    ''' Fill TreeView Directories from archive.
    ''' </summary>
    ''' <param name="TreeViewEntryes"></param>
    Private Sub FillTreeView(ByVal TreeViewEntryes As TreeView)
        'Closing Archive.
        CloseArchive()
        'Clearing TreeView and ListView.
        TreeViewEntryes.Sort()
        TreeViewEntryes.Nodes.Clear()
        LstEntrys.Clear()

        Try
            Archive = ArchiveFactory.Open(szArchivePath)
            Dim _ImgListFolders As New List(Of Image)()
            'Path to folder icon.
            Dim folder As String = _
                Environment.GetFolderPath(Environment.SpecialFolder.Windows)
            'Adding folder icon to list.
            _ImgListFolders.Add(GetFolderIcon(folder, False))
            'Adding folder icon from list, using ImageList.
            ImgListTree.Images.AddRange(_ImgListFolders.ToArray())
            ImgListTree.Images.Add(GetFileIcon(Path.GetExtension(szArchivePath), _
                                   IconSize.SHGFI_SMALLICON))
            'Adding first node, with archive name.
            TreeViewEntryes.Nodes.Add(Path.GetFileName(szArchivePath))
            'Set image for first node.
            TreeViewEntryes.Nodes(0).ImageIndex = ImgListTree.Images.Count - 1
            TreeViewEntryes.Nodes(0).SelectedImageIndex = ImgListTree.Images.Count - 1

            'Getting all files from archive.
            For Each iEntry In Archive.Entries.Where(Function(e) Not e.IsDirectory)
                If Archive IsNot Nothing Then
                    'Collecting extension from archive and adding to a list.
                    GetFileType(Path.GetExtension(iEntry.Key), _ImgListFileType)
                End If
            Next iEntry

            ListIcons()

            For Each _Entry In Archive.Entries.Where(Function(e) e.IsDirectory)
                Dim nodes As TreeNodeCollection = TreeViewEntryes.Nodes(0).Nodes

                If Archive.Type = ArchiveType.Rar Then
                    TreeEntryes.PathSeparator = "\"
                    For Each PathSep As String In _Entry.Key.Split("\"c)
                        If Not nodes.ContainsKey(PathSep) Then
                            nodes.Add(PathSep, PathSep)
                        End If
                        nodes = nodes(PathSep).Nodes
                    Next PathSep

                ElseIf Archive.Type = ArchiveType.Zip Then
                    TreeEntryes.PathSeparator = "/"
                    For Each PathSep As String In _Entry.Key.TrimEnd("/").Split("/"c)
                        If Not nodes.ContainsKey(PathSep) Then
                            nodes.Add(PathSep, PathSep)
                        End If
                        nodes = nodes(PathSep).Nodes
                    Next PathSep
                End If

            Next _Entry
            TreeViewEntryes.Focus()
            TreeViewEntryes.Nodes(0).Expand()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub

#End Region

#Region " Fill ListView"
    ''' <summary>
    ''' Fill ListView files from archive entries when TreeView node is selected.
    ''' </summary>
    ''' <param name="ListEntrys"></param>
    Private Sub FillListView(ByVal ListEntrys As ListView)
        ' ListView clearing
        ListEntrys.Items.Clear()
        listViewItems.Clear()

        'Getting all files from archive
        For Each Entry In Archive.Entries.Where(Function(D) Not D.IsDirectory)
            If Path.GetExtension(Entry.Key) = Nothing Then
                listViewItem = New ListViewItem(Path.GetFileName(Entry.Key), _
                               ImgLargeListView.Images.IndexOfKey("Empty"))
            Else
                listViewItem = New ListViewItem(Path.GetFileName(Entry.Key), _
                          ImgLargeListView.Images.IndexOfKey(Path.GetExtension(Entry.Key)))
            End If
            If TreeEntryes.Nodes(0).IsSelected Then
                If Entry.Key.StartsWith(Path.GetFileName(Entry.Key)) Then
                    listViewItems.Add(listViewItem)
                End If
            Else
                Dim szRarFullPathReplace As String = _
                          TreeEntryes.SelectedNode.FullPath.Replace_
                          (Path.GetFileName(szArchivePath), "").TrimStart("\")
                Dim szRarSelectedNode As String = Entry.Key.StartsWith_
                          (szRarFullPathReplace & "\" & Path.GetFileName(Entry.Key))

                Dim szZipFullPathReplace As String = _
                             TreeEntryes.SelectedNode.FullPath.Replace_
                             (Path.GetFileName(szArchivePath), "").TrimStart("/")
                Dim szZipSelectedNode As String = _
                             Entry.Key.StartsWith(szZipFullPathReplace & "/" & _
                             Path.GetFileName(Entry.Key))

                If szRarSelectedNode OrElse szZipSelectedNode Then
                    listViewItems.Add(listViewItem)
                End If
            End If
        Next Entry
        ListEntrys.Items.AddRange(listViewItems.ToArray())

    End Sub

#End Region 

End Class

Button Click 事件中,我调用 _OpenRarDlg 作为新的 OpenFileDialog 来打开 .rar.zip 文件。

#Region " Button Open "
    Private Sub BtnOpen_Click(sender As Object, e As EventArgs) Handles BtnOpen.Click
        Dim _OpenRarDlg As New OpenFileDialog
        With _OpenRarDlg
            .DefaultExt = ".rar"
            .Filter = "Supported Files (*.rar, *.zip)|*.rar;*.zip"
        End With

        If _OpenRarDlg.ShowDialog = DialogResult.OK Then
            szArchivePath = _OpenRarDlg.FileName
            FillTreeView(TreeEntryes)
        End If

    End Sub
#End Region

TreeView AfterSelect 事件中,我调用 FillListView(LstEntrys)。当 TreeView 节点(目录)被选中时,如果该目录包含文件,则所有文件都将显示在 ListView 中。

#Region " TreeView AfterSelect Event "
    Private Sub TreeEntryes_AfterSelect(sender As Object, e As TreeViewEventArgs) _
            Handles TreeEntryes.AfterSelect
        FillListView(LstEntrys)
    End Sub
#End Region 

FormClosed 事件中,应关闭归档文件。

#Region " On Form Closed Event "
    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        MyBase.OnFormClosed(e)
        CloseArchive()
    End Sub
#End Region 

现在是 Module。这个 Module 是为了通过扩展获取每个文件类型的图标,我决定将这个 Module 放在 Form 类中,因为我不想为此 Module 创建一个新的 .vb 文件。

#Region " Get Icon Module"
Module GetIcon
    Private Const MAX_PATH As Int32 = 260
    Private Const SHGFI_ICON As Int32 = &H100
    Private Const SHGFI_USEFILEATTRIBUTES As Int32 = &H10
    Private Const FILE_ATTRIBUTE_NORMAL As Int32 = &H80
    Private Const SHGFI_LARGEICON As Integer = &H0
    Private Const SHGFI_SMALLICON As Integer = &H1

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
    Private Structure SHFILEINFO
        Public hIcon As IntPtr
        Public iIcon As Integer
        Public dwAttributes As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)>
        Public szDisplayName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
        Public szTypeName As String
    End Structure

    Public Enum IconSize
        SHGFI_LARGEICON = 0
        SHGFI_SMALLICON = 1
    End Enum

    <DllImport("shell32.dll", CharSet:=CharSet.Auto)>
    Private Function SHGetFileInfoW(<[In](), MarshalAs(UnmanagedType.LPTStr)> _
        ByVal pszPath As String, ByVal dwFileAttributes As Int32, _
        ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Int32, ByVal uFlags As Int32) As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True)>
    Private Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean
    End Function

    Public Function GetFileIcon(ByVal fileExt As String, _
        Optional ByVal ICOsize As IconSize = IconSize.SHGFI_LARGEICON) As Bitmap
        Dim shinfo As New SHFILEINFO
        shinfo.szDisplayName = New String(Chr(0), MAX_PATH)
        shinfo.szTypeName = New String(Chr(0), 80)
        SHGetFileInfoW(fileExt, FILE_ATTRIBUTE_NORMAL, shinfo, _
           Marshal.SizeOf(shinfo), SHGFI_ICON Or ICOsize Or SHGFI_USEFILEATTRIBUTES)
        Dim bmp As Bitmap = Icon.FromHandle(shinfo.hIcon).ToBitmap
        DestroyIcon(shinfo.hIcon) ' must destroy icon to avoid GDI leak!
        Return bmp ' return icon as a bitmap
    End Function

    Public Function GetFolderIcon_
        (ByVal PathName As String, ByVal LargeIco As Boolean) As Bitmap
        Dim fi As New SHFILEINFO
        If LargeIco Then
            SHGetFileInfoW(PathName, 0, fi, Marshal.SizeOf(fi), SHGFI_ICON Or SHGFI_LARGEICON)
        Else
            SHGetFileInfoW(PathName, 0, fi, Marshal.SizeOf(fi), SHGFI_ICON Or SHGFI_SMALLICON)
        End If
        Dim bm As Bitmap = Icon.FromHandle(fi.hIcon).ToBitmap
        DestroyIcon(fi.hIcon)
        Return bm
    End Function

End Module

#End Region

整个 Form 代码如下所示

#Region " Imports "
Option Explicit On
Imports System.IO
Imports System.Runtime.InteropServices
Imports SharpCompress.Archives
Imports SharpCompress.Common

#End Region

Public Class Form1 : Inherits Form

#Region " Declares "

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Code Quality", _
        "IDE0069:Disposable fields should be disposed", Justification:="<Pending>")>
    Private WithEvents Archive As IArchive
    Private szArchivePath As String
    Private ReadOnly listViewItems As New List(Of ListViewItem)()
    Public listViewItem As ListViewItem
    Private ReadOnly _ImgListFileType As New List(Of String)() From {"Empty"}

#End Region

#Region " GetFileType "
    ''' <summary>
    ''' Collecting file extension and avoiding duplicate. Example: .exe, .txt, .jpg, etc.
    ''' </summary>
    ''' <param name="GetFrom"></param>
    ''' <param name="SearchIn"></param>
    Private Sub GetFileType(ByVal GetFrom As String, SearchIn As List(Of String))
        If Not SearchIn.Contains(GetFrom) Then
            SearchIn.Add(GetFrom)
            SearchIn.Remove(String.Empty)
        End If
    End Sub
#End Region

#Region " List Icons "
    ''' <summary>
    ''' List icons for each file type.
    ''' </summary>
    Private Sub ListIcons()
        'Getting each file type from list "_ImgListFileType" List(Of String)
        For Each iFound In _ImgListFileType
            If Not iFound = Nothing Then
                'Avoid duplication of images.
                If Not ImgLargeListView.Images.ContainsKey(iFound) Then
                    'To avoid "Cross-thread operation not valid" 
                    'when using Background Worker or some Thread.
                    'Adding images using GetIcon Module
                    If InvokeRequired Then
                        Invoke(Sub() ImgListView.Images.Add(iFound, _
                               GetFileIcon(iFound, IconSize.SHGFI_SMALLICON)))
                        Invoke(Sub() ImgLargeListView.Images.Add(iFound, _
                               GetFileIcon(iFound, IconSize.SHGFI_LARGEICON)))
                    Else
                        ImgListView.Images.Add(iFound, _
                               GetFileIcon(iFound, IconSize.SHGFI_SMALLICON))
                        ImgLargeListView.Images.Add(iFound, _
                               GetFileIcon(iFound, IconSize.SHGFI_LARGEICON))
                    End If
                End If
            End If
        Next iFound
    End Sub
#End Region

#Region " Close Archive "
    ''' <summary>
    ''' Closing the archive.
    ''' </summary>
    Private Sub CloseArchive()
        If Not (Archive Is Nothing) Then
            Archive.Dispose()
        End If
    End Sub
#End Region

#Region " Fill TreeView "
    ''' <summary>
    ''' Fill TreeView Directories from archive.
    ''' </summary>
    ''' <param name="TreeViewEntryes"></param>
    Private Sub FillTreeView(ByVal TreeViewEntryes As TreeView)
        'Closing Archive.
        CloseArchive()
        'Clearing TreeView and ListView.
        TreeViewEntryes.Sort()
        TreeViewEntryes.Nodes.Clear()
        LstEntrys.Clear()

        Try
            Archive = ArchiveFactory.Open(szArchivePath)
            Dim _ImgListFolders As New List(Of Image)()
            'Path to folder icon.
            Dim folder As String = _
                   Environment.GetFolderPath(Environment.SpecialFolder.Windows)
            'Adding folder icon to list.
            _ImgListFolders.Add(GetFolderIcon(folder, False))
            'Adding folder icon from list, using ImageList.
            ImgListTree.Images.AddRange(_ImgListFolders.ToArray())
            ImgListTree.Images.Add(GetFileIcon(Path.GetExtension(szArchivePath), _
                                   IconSize.SHGFI_SMALLICON))
            'Adding first node, with archive name.
            TreeViewEntryes.Nodes.Add(Path.GetFileName(szArchivePath))
            'Set image for first node.
            TreeViewEntryes.Nodes(0).ImageIndex = ImgListTree.Images.Count - 1
            TreeViewEntryes.Nodes(0).SelectedImageIndex = ImgListTree.Images.Count - 1

            'Getting all files from archive.
            For Each iEntry In Archive.Entries.Where(Function(e) Not e.IsDirectory)
                If Archive IsNot Nothing Then
                    'Collecting extension from archive and adding to a list.
                    GetFileType(Path.GetExtension(iEntry.Key), _ImgListFileType)
                End If
            Next iEntry

            ListIcons()

            For Each _Entry In Archive.Entries.Where(Function(e) e.IsDirectory)
                Dim nodes As TreeNodeCollection = TreeViewEntryes.Nodes(0).Nodes

                If Archive.Type = ArchiveType.Rar Then
                    TreeEntryes.PathSeparator = "\"
                    For Each PathSep As String In _Entry.Key.Split("\"c)
                        If Not nodes.ContainsKey(PathSep) Then
                            nodes.Add(PathSep, PathSep)
                        End If
                        nodes = nodes(PathSep).Nodes
                    Next PathSep

                ElseIf Archive.Type = ArchiveType.Zip Then
                    TreeEntryes.PathSeparator = "/"
                    For Each PathSep As String In _Entry.Key.TrimEnd("/").Split("/"c)
                        If Not nodes.ContainsKey(PathSep) Then
                            nodes.Add(PathSep, PathSep)
                        End If
                        nodes = nodes(PathSep).Nodes
                    Next PathSep
                End If

            Next _Entry
            TreeViewEntryes.Focus()
            TreeViewEntryes.Nodes(0).Expand()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub

#End Region

#Region " Fill ListView"
    ''' <summary>
    ''' Fill ListView files from archive entries when TreeView node is selected.
    ''' </summary>
    ''' <param name="ListEntrys"></param>
    Private Sub FillListView(ByVal ListEntrys As ListView)
        ' ListView clearing
        ListEntrys.Items.Clear()
        listViewItems.Clear()

        'Getting all files from archive
        For Each Entry In Archive.Entries.Where(Function(D) Not D.IsDirectory)
            If Path.GetExtension(Entry.Key) = Nothing Then
                listViewItem = New ListViewItem(Path.GetFileName(Entry.Key), _
                               ImgLargeListView.Images.IndexOfKey("Empty"))
            Else
                listViewItem = New ListViewItem(Path.GetFileName(Entry.Key), _
                    ImgLargeListView.Images.IndexOfKey(Path.GetExtension(Entry.Key)))
            End If
            If TreeEntryes.Nodes(0).IsSelected Then
                If Entry.Key.StartsWith(Path.GetFileName(Entry.Key)) Then
                    listViewItems.Add(listViewItem)
                End If
            Else
                Dim szRarFullPathReplace As String = _
                        TreeEntryes.SelectedNode.FullPath.Replace_
                        (Path.GetFileName(szArchivePath), "").TrimStart("\")
                Dim szRarSelectedNode As String = _
                        Entry.Key.StartsWith(szRarFullPathReplace & "\" & _
                        Path.GetFileName(Entry.Key))

                Dim szZipFullPathReplace As String = _
                        TreeEntryes.SelectedNode.FullPath.Replace_
                        (Path.GetFileName(szArchivePath), "").TrimStart("/")
                Dim szZipSelectedNode As String = _
                        Entry.Key.StartsWith(szZipFullPathReplace & "/" & _
                        Path.GetFileName(Entry.Key))

                If szRarSelectedNode OrElse szZipSelectedNode Then
                    listViewItems.Add(listViewItem)
                End If
            End If
        Next Entry
        ListEntrys.Items.AddRange(listViewItems.ToArray())

    End Sub

#End Region

#Region " Button Open "
    Private Sub BtnOpen_Click(sender As Object, e As EventArgs) Handles BtnOpen.Click
        Dim _OpenRarDlg As New OpenFileDialog
        With _OpenRarDlg
            .DefaultExt = ".rar"
            .Filter = "Supported Files (*.rar, *.zip)|*.rar;*.zip"
        End With

        If _OpenRarDlg.ShowDialog = DialogResult.OK Then
            szArchivePath = _OpenRarDlg.FileName
            FillTreeView(TreeEntryes)
        End If

    End Sub
#End Region

#Region " TreeView AfterSelect Event "
    Private Sub TreeEntryes_AfterSelect(sender As Object, e As TreeViewEventArgs) _
            Handles TreeEntryes.AfterSelect
        FillListView(LstEntrys)
    End Sub
#End Region

#Region " On Form Closed Event "
    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        MyBase.OnFormClosed(e)
        CloseArchive()
    End Sub
#End Region

End Class

#Region " Get Icon Module"
Module GetIcon
    Private Const MAX_PATH As Int32 = 260
    Private Const SHGFI_ICON As Int32 = &H100
    Private Const SHGFI_USEFILEATTRIBUTES As Int32 = &H10
    Private Const FILE_ATTRIBUTE_NORMAL As Int32 = &H80
    Private Const SHGFI_LARGEICON As Integer = &H0
    Private Const SHGFI_SMALLICON As Integer = &H1

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
    Private Structure SHFILEINFO
        Public hIcon As IntPtr
        Public iIcon As Integer
        Public dwAttributes As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)>
        Public szDisplayName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
        Public szTypeName As String
    End Structure

    Public Enum IconSize
        SHGFI_LARGEICON = 0
        SHGFI_SMALLICON = 1
    End Enum

    <DllImport("shell32.dll", CharSet:=CharSet.Auto)>
    Private Function SHGetFileInfoW(<[In](), MarshalAs(UnmanagedType.LPTStr)> _
       ByVal pszPath As String, ByVal dwFileAttributes As Int32, _
       ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Int32, ByVal uFlags As Int32) As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True)>
    Private Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean
    End Function

    Public Function GetFileIcon(ByVal fileExt As String, _
        Optional ByVal ICOsize As IconSize = IconSize.SHGFI_LARGEICON) As Bitmap
        Dim shinfo As New SHFILEINFO
        shinfo.szDisplayName = New String(Chr(0), MAX_PATH)
        shinfo.szTypeName = New String(Chr(0), 80)
        SHGetFileInfoW(fileExt, FILE_ATTRIBUTE_NORMAL, shinfo, _
           Marshal.SizeOf(shinfo), SHGFI_ICON Or ICOsize Or SHGFI_USEFILEATTRIBUTES)
        Dim bmp As Bitmap = Icon.FromHandle(shinfo.hIcon).ToBitmap
        DestroyIcon(shinfo.hIcon) ' must destroy icon to avoid GDI leak!
        Return bmp ' return icon as a bitmap
    End Function

    Public Function GetFolderIcon(ByVal PathName As String, _
              ByVal LargeIco As Boolean) As Bitmap
        Dim fi As New SHFILEINFO
        If LargeIco Then
            SHGetFileInfoW(PathName, 0, fi, _
                Marshal.SizeOf(fi), SHGFI_ICON Or SHGFI_LARGEICON)
        Else
            SHGetFileInfoW(PathName, 0, fi, _
                Marshal.SizeOf(fi), SHGFI_ICON Or SHGFI_SMALLICON)
        End If
        Dim bm As Bitmap = Icon.FromHandle(fi.hIcon).ToBitmap
        DestroyIcon(fi.hIcon)
        Return bm
    End Function

End Module

#End Region

历史

  • 2019 年 10 月 6 日:初始版本
© . All rights reserved.