Question

This question is related to Visual Basic .NET 2010

How do I enumerate the "native" resources (such as icon, version info, etc) of a win32 executable file?

I found little to no documentation on it, and what I found simply did not work. I've tried the example provided here so far http://www.pinvoke.net/default.aspx/kernel32.EnumResourceNames. It's all I could find on the subject.

Help is much appreciated.

Was it helpful?

Solution

It isn't that clear what your hangup might be. The declarations you found at pinvoke.net are only so-so, not an uncommon problem. The probable hangup is that both the resource type and the resource name can either be a number or a string. So the pinvoke declaration should declare them as IntPtr and, if they have the right value, convert them to a string dynamically.

Another thing you have to do is to first enumerate the resource types in the file, then enumerate the resources of that type.

Some code to play with:

Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Linq

Module Module1
    Sub Main()
        Dim handle = LoadLibrary("user32.dll")
        If handle = IntPtr.Zero Then
            Throw New Win32Exception
        End If
        If Not EnumResourceTypes(handle, AddressOf EnumTypesCallback, IntPtr.Zero) Then
            Throw New Win32Exception
        End If
        Console.ReadLine()
    End Sub

    Function EnumTypesCallback(hModule As IntPtr, lpszType As IntPtr, lParam As IntPtr) As Boolean
        EnumResourceNames(hModule, lpszType, AddressOf EnumResourceCallback, IntPtr.Zero)
        Return True
    End Function

    Function EnumResourceCallback(hModule As IntPtr, lpszType As IntPtr, ByVal lpszName As IntPtr, ByVal lParam As IntPtr) As Boolean
        Dim type As String = lpszType.ToInt32().ToString()
        If [Enum].GetValues(GetType(ResourceType)).Cast(Of Integer).Contains(lpszType.ToInt32()) Then
            type = [Enum].GetName(GetType(ResourceType), lpszType.ToInt32())
        ElseIf lpszType.ToInt32() > &HFFFF Then
            type = Marshal.PtrToStringUni(lpszType)
        End If
        Dim name As String = lpszName.ToInt32().ToString()
        If lpszName.ToInt32() > &HFFFF Then
            name = Marshal.PtrToStringUni(lpszName)
        End If
        Console.WriteLine("Resource type={0}, id={1}", type, name)
        Return True
    End Function


    Private Delegate Function EnumResNameProcDelegate(ByVal hModule As IntPtr, ByVal lpszType As IntPtr, ByVal lpszName As IntPtr, ByVal lParam As IntPtr) As Boolean
    Private Delegate Function EnumResTypeProc(hModule As IntPtr, lpszType As IntPtr, lParam As IntPtr) As Boolean

    <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Public Function LoadLibrary(ByVal lpFileName As String) As IntPtr
    End Function

    <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Function EnumResourceTypes(ByVal hModule As IntPtr, ByVal lpEnumFunc As EnumResTypeProc, ByVal lParam As IntPtr) As Boolean
    End Function

    <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Function EnumResourceNames(ByVal hModule As IntPtr, ByVal lpszType As IntPtr, ByVal lpEnumFunc As EnumResNameProcDelegate, ByVal lParam As IntPtr) As Boolean
    End Function

    Public Enum ResourceType
        CURSOR = 1
        BITMAP = 2
        ICON = 3
        MENU = 4
        DIALOG = 5
        [STRING] = 6
        FONTDIR = 7
        FONT = 8
        ACCELERATOR = 9
        RCDATA = 10
        MESSAGETABLE = 11
        GROUP_CURSOR = 12
        GROUP_ICON = 14
        VERSION = 16
        DLGINCLUDE = 17
        PLUGPLAY = 19
        VXD = 20
        ANICURSOR = 21
        ANIICON = 22
        HTML = 23
        MANIFEST = 24
    End Enum
End Module

Output on Windows 8.1:

Resource type=MUI, id=1
Resource type=WEVT_TEMPLATE, id=1
Resource type=CURSOR, id=92
Resource type=CURSOR, id=93
etc...
Resource type=BITMAP, id=36
Resource type=BITMAP, id=136
etc..
Resource type=ICON, id=1
Resource type=ICON, id=2
etc..
Resource type=MENU, id=1
Resource type=MENU, id=4
etc..
Resource type=DIALOG, id=9
Resource type=STRING, id=1
Resource type=STRING, id=44
etc..
Resource type=MESSAGETABLE, id=1
Resource type=GROUP_CURSOR, id=100
Resource type=GROUP_CURSOR, id=101
etc..
Resource type=GROUP_ICON, id=100
Resource type=GROUP_ICON, id=101
etc..
Resource type=VERSION, id=1
Resource type=ANICURSOR, id=32665
Resource type=ANICURSOR, id=32666
Resource type=ANICURSOR, id=32669

Compare to what you see when you use File + Open + File, select c:\windows\syswow64\user32.dll (won't work on Express).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top