Vb.net 正在尝试加载应用程序';使用LoadImage的图标,但函数返回0

Vb.net 正在尝试加载应用程序';使用LoadImage的图标,但函数返回0,vb.net,winapi,icons,native-methods,Vb.net,Winapi,Icons,Native Methods,我试图使用LoadImageWinAPI函数加载应用程序的图标,但由于某些原因,它总是返回0 我读过这本书,但我不明白我做错了什么。除了尝试将IconPtr转换为Icon(这是因为IconPtr为0)时,我没有例外 NativeMethods类: Public Class NativeMethods <DllImport("user32.dll", SetLastError:=True)> _ Public Shared Function LoadImage(ByVa

我试图使用
LoadImage
WinAPI函数加载应用程序的图标,但由于某些原因,它总是返回0

我读过这本书,但我不明白我做错了什么。除了尝试将
IconPtr
转换为
Icon
(这是因为
IconPtr
为0)时,我没有例外

NativeMethods
类:

Public Class NativeMethods
    <DllImport("user32.dll", SetLastError:=True)> _
    Public Shared Function LoadImage(ByVal hInst As IntPtr, _
                     ByVal lpszName As String,
                     ByVal uType As UInt32, _
                     ByVal cxDesired As Integer, _
                     ByVal cyDesired As Integer, _
                     ByVal fuLoad As UInt32) As IntPtr
    End Function

    Public Enum Enumrations As UInteger
        '' LoadImage ''
        IMAGE_BITMAP = 0
        IMAGE_ICON = 1
        IMAGE_CURSOR = 2
        LR_CREATEDIBSECTION = &H2000
        LR_DEFAULTCOLOR = &H0
        LR_DEFAULTSIZE = &H40
        LR_LOADFROMFILE = &H10
        LR_LOADMAP3DCOLORS = &H1000
        LR_LOADTRANSPARENT = &H20
        LR_MONOCHROME = &H1
        LR_SHARED = &H8000
        LR_VGACOLOR = &H80
    End Enum
End Class
Public NotInheritable Class AssemblyIconCollection
    ''' <summary>
    ''' Gets or sets the large icons found in the assembly.
    ''' </summary>
    ''' <remarks></remarks>
    Public Property LargeIcons As List(Of Icon)

    ''' <summary>
    ''' Gets or sets the small icons found in the assembly.
    ''' </summary>
    ''' <remarks></remarks>
    Public Property SmallIcons As List(Of Icon)

    Public Sub New()
        Me.LargeIcons = New List(Of Icon)
        Me.SmallIcons = New List(Of Icon)
    End Sub
End Class

你走错了路。您正在将可执行文件名传递给
LoadImage
lpszName
参数。该参数不接受可执行文件名。它接受第一个参数hinst指定的模块内的资源名称。文档中对此进行了解释

您注意到没有遇到异常。这是意料之中的。Win32 API不会引发异常。同样,文档描述了如何报告错误。它们通过返回值
NULL
报告。当这种情况发生时,调用
GetLastError
获取错误代码。这将是.net中的
Marshal.GetLastWin32Error

要使用
LoadImage
执行您正在尝试的操作,您需要执行以下操作:

  • 通过调用
    LoadLibraryEx
    传递可执行文件名来获取实例句柄。如文档所述,使用
    LOAD\u LIBRARY\u AS\u DATAFILE
    标志
  • 将该实例句柄传递给
    LoadImage
    。您还需要知道要提取的图像资源的名称
  • 如果您不知道资源的名称,则需要使用资源枚举函数,例如
    EnumResourceNames
    。您正在寻找可执行文件中的第一个资源
    你走错了路。您正在将可执行文件名传递给
    LoadImage
    lpszName
    参数。该参数不接受可执行文件名。它接受第一个参数hinst指定的模块内的资源名称。文档中对此进行了解释

    您注意到没有遇到异常。这是意料之中的。Win32 API不会引发异常。同样,文档描述了如何报告错误。它们通过返回值
    NULL
    报告。当这种情况发生时,调用
    GetLastError
    获取错误代码。这将是.net中的
    Marshal.GetLastWin32Error

    要使用
    LoadImage
    执行您正在尝试的操作,您需要执行以下操作:

  • 通过调用
    LoadLibraryEx
    传递可执行文件名来获取实例句柄。如文档所述,使用
    LOAD\u LIBRARY\u AS\u DATAFILE
    标志
  • 将该实例句柄传递给
    LoadImage
    。您还需要知道要提取的图像资源的名称
  • 如果您不知道资源的名称,则需要使用资源枚举函数,例如
    EnumResourceNames
    。您正在寻找可执行文件中的第一个资源
    你走错了路。您正在将可执行文件名传递给
    LoadImage
    lpszName
    参数。该参数不接受可执行文件名。它接受第一个参数hinst指定的模块内的资源名称。文档中对此进行了解释

    您注意到没有遇到异常。这是意料之中的。Win32 API不会引发异常。同样,文档描述了如何报告错误。它们通过返回值
    NULL
    报告。当这种情况发生时,调用
    GetLastError
    获取错误代码。这将是.net中的
    Marshal.GetLastWin32Error

    要使用
    LoadImage
    执行您正在尝试的操作,您需要执行以下操作:

  • 通过调用
    LoadLibraryEx
    传递可执行文件名来获取实例句柄。如文档所述,使用
    LOAD\u LIBRARY\u AS\u DATAFILE
    标志
  • 将该实例句柄传递给
    LoadImage
    。您还需要知道要提取的图像资源的名称
  • 如果您不知道资源的名称,则需要使用资源枚举函数,例如
    EnumResourceNames
    。您正在寻找可执行文件中的第一个资源
    你走错了路。您正在将可执行文件名传递给
    LoadImage
    lpszName
    参数。该参数不接受可执行文件名。它接受第一个参数hinst指定的模块内的资源名称。文档中对此进行了解释

    您注意到没有遇到异常。这是意料之中的。Win32 API不会引发异常。同样,文档描述了如何报告错误。它们通过返回值
    NULL
    报告。当这种情况发生时,调用
    GetLastError
    获取错误代码。这将是.net中的
    Marshal.GetLastWin32Error

    要使用
    LoadImage
    执行您正在尝试的操作,您需要执行以下操作:

  • 通过调用
    LoadLibraryEx
    传递可执行文件名来获取实例句柄。如文档所述,使用
    LOAD\u LIBRARY\u AS\u DATAFILE
    标志
  • 将该实例句柄传递给
    LoadImage
    。您还需要知道要提取的图像资源的名称
  • 如果您不知道资源的名称,则需要使用资源枚举函数,例如
    EnumResourceNames
    。您正在寻找中的第一个资源
    Dim Icons() As Icon = ExtractAssociatedIconArray("C:\MyApp.exe", New Size() {New Size() {48, 48}})
    
    Public Shared Function ExtractAssociatedIcons(ByVal File As String) As AssemblyIconCollection
        Dim IconCount As Integer = NativeMethods.ExtractIconEx(File, -1, Nothing, Nothing, 0)
        Dim AssemblyIcons As New AssemblyIconCollection
    
        'The 'Icon handle' arrays.
        Dim LargeIcons(IconCount) As IntPtr
        Dim SmallIcons(IconCount) As IntPtr
    
        'Extract icons into the two arrays of handles.
        NativeMethods.ExtractIconEx(File, 0, LargeIcons, SmallIcons, IconCount)
    
        'Add each large icon to the "LargeIcons" list.
        For Each ptr As IntPtr In LargeIcons
            If ptr = IntPtr.Zero Then Continue For
    
            Dim Ico As Icon = Icon.FromHandle(ptr)
            If Ico.Width < 25 Or Ico.Height < 25 Then Continue For
            AssemblyIcons.LargeIcons.Add(Ico)
        Next
    
        'Add each small icon to the "SmallIcons" list.
        For Each ptr As IntPtr In SmallIcons
            If ptr = IntPtr.Zero Then Continue For
    
            Dim Ico As Icon = Icon.FromHandle(ptr)
            If Ico.Width > 24 Or Ico.Height > 24 Then Continue For
            AssemblyIcons.SmallIcons.Add(Ico)
        Next
    
        'Return the output class.
        Return AssemblyIcons
    End Function
    
    Public NotInheritable Class AssemblyIconCollection
        ''' <summary>
        ''' Gets or sets the large icons found in the assembly.
        ''' </summary>
        ''' <remarks></remarks>
        Public Property LargeIcons As List(Of Icon)
    
        ''' <summary>
        ''' Gets or sets the small icons found in the assembly.
        ''' </summary>
        ''' <remarks></remarks>
        Public Property SmallIcons As List(Of Icon)
    
        Public Sub New()
            Me.LargeIcons = New List(Of Icon)
            Me.SmallIcons = New List(Of Icon)
        End Sub
    End Class
    
    Public Class NativeMethods
        <DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
        Public Shared Function ExtractIconEx(ByVal szFileName As String, _
             ByVal nIconIndex As Integer, _
             ByVal phiconLarge() As IntPtr, _
             ByVal phiconSmall() As IntPtr, _
             ByVal nIcons As UInteger) As UInteger
        End Function
    End Class
    
    Dim Icons As AssemblyIconCollection = ExtractAssociatedIcons("C:\myfile.exe")
    
    'Iterating every large icon.
    For Each LargeIcon As Icon In Icons.LargeIcons
        'Do stuff.
    Next
    
    'Iterating every small icon.
    For Each SmallIcon As Icon In Icons.SmallIcons
        'Do stuff.
    Next