0

I have the below code to load an icon using Shell32 dll. It works fine on my machine. But one of the systems in production environment got an exception saying "System.ArgumentException: Win32 handle that was passed to Icon is not valid or is the wrong type". Any idea why we get this error? Thank you!

Public Function GetExecutableIcon() As Icon
    Dim large As IntPtr
    Dim small As IntPtr
    ExtractIconEx(Application.ExecutablePath, 0, large, small, 1)

    Return Icon.FromHandle(small)

End Function

<DllImport("Shell32")> _
Public Shared Function ExtractIconEx(ByVal sFile As String, ByVal iIndex As Integer, 
                 ByRef piLargeVersion As IntPtr, ByRef piSmallVersion As IntPtr, 
                 ByVal amountIcons As Integer) As Integer

End Function
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
Jyina
  • 2,530
  • 9
  • 42
  • 80

2 Answers2

1

Is your declaration correct? http://www.pinvoke.net/default.aspx/shell32.ExtractIconEx shows

<DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
 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
weloytty
  • 5,808
  • 5
  • 28
  • 35
1

Try this:

<DllImport("Shell32")> _
Public Shared Function ExtractIconEx(ByVal sFile As String, ByVal iIndex As Integer, 
             ByRef piLargeVersion As IntPtr, ByRef piSmallVersion As IntPtr, 
             ByVal amountIcons As Integer) As Integer

Public Function GetExecutableIcon() As Icon
    Dim num As Integer = 10
    Dim large(num - 1) As IntPtr
    Dim small(num - 1) As IntPtr

    ExtractIconEx("C:\Windows\System32\Shell32.dll", 0, large(0), small(0), num)

    Return Icon.FromHandle(small(6)) 'change the index accordingly

End Function
  • I tried the above code that was suggested and it works fine on my machine. However, I don't understand though what would be the difference between passing the first value from the array like large(0), small(0) and large, small because ExtractIconEx is defined to take IntPtr and not an array of IntPtrs ? Thank you! – Jyina Oct 20 '14 at 19:19
  • @Jyina You are not passing the value of `large(0)`or `small(0)` but the address of them. The declaration of `ExtractIconEx` is **ByRef**. You can not pass `large, small` because it expects pointers not arrays. – γηράσκω δ' αεί πολλά διδασκόμε Oct 20 '14 at 19:26
  • Thank you for this. Converted to c# and switched to this code from `SHGetFileInfo` as `SHGetFileInfo` is not parallel processing friendly; giving the error as stated in the original question - randomly. One thing to note, is that using this method, you don't get the registered index of the icon set as the display icon for the application, it doesn't take advantage of windows cache, and if no icon exists in the file, an exception is thrown you must trap for (which is where you would manually set a default icon for return result) – Kraang Prime Aug 01 '16 at 04:55