此问题与Visual Basic .NET 2010
有关如何枚举win32可执行文件的“本机”资源(如图标,版本信息等)?
我发现很少甚至没有文档,而我发现的根本没用。到目前为止,我已尝试过此处提供的示例http://www.pinvoke.net/default.aspx/kernel32.EnumResourceNames。这就是我能找到的关于这个主题的全部内容。
非常感谢帮助。
答案 0 :(得分:2)
不清楚你的挂断可能是什么。你在pinvoke.net上发现的声明只是马马虎虎,而不是一个不寻常的问题。可能的挂起是资源类型和资源名称都可以是数字或字符串。所以pinvoke声明应该将它们声明为IntPtr,如果它们具有正确的值,则将它们动态转换为字符串。
您需要做的另一件事是首先枚举文件中的资源类型,然后枚举该类型的资源。
可以使用的一些代码:
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
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
与使用File + Open + File时看到的内容相比,选择c:\ windows \ syswow64 \ user32.dll(赢得了对Express的工作)。