November 9, 2004
EnumResourceNames in C#
EnumResourceNames is one of the tricky functions which uses a callback.
But the main problem is, that in the callback it either returns IDs or strings in the same parameter! To call this function from C# you have to do some own marshaling… To differentiate between IDs and strings they did a simple trick: If the higher part of the DWORD is 0, then it is an ID. It uses that fact that you cannot allocate memory in the region of 0×00000000 to 0×0000FFFF.
Here is a full working example which also handles IDs/strings (I also added this example to pinvoke.net)
using System;
using System.Runtime.InteropServices;
namespace EnumResNamesCS
{
class Class1
{
private const uint RT_CURSOR = 0x00000001;
private const uint RT_BITMAP = 0x00000002;
private const uint RT_ICON = 0x00000003;
private const uint RT_MENU = 0x00000004;
private const uint RT_DIALOG = 0x00000005;
private const uint RT_STRING = 0x00000006;
private const uint RT_FONTDIR = 0x00000007;
private const uint RT_FONT = 0x00000008;
private const uint RT_ACCELERATOR = 0x00000009;
private const uint RT_RCDATA = 0x00000010;
private const uint RT_MESSAGETABLE = 0x00000011;
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibraryEx(
string lpFileName,
IntPtr hFile,
uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", EntryPoint = "EnumResourceNamesW",
CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool EnumResourceNamesWithName(
IntPtr hModule,
string lpszType,
EnumResNameDelegate lpEnumFunc,
IntPtr lParam);
[DllImport("kernel32.dll", EntryPoint = "EnumResourceNamesW",
CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool EnumResourceNamesWithID(
IntPtr hModule,
uint lpszType,
EnumResNameDelegate lpEnumFunc,
IntPtr lParam);
private delegate bool EnumResNameDelegate(
IntPtr hModule,
IntPtr lpszType,
IntPtr lpszName,
IntPtr lParam);
private static bool IS_INTRESOURCE(IntPtr value)
{
if ( ((uint) value) > ushort.MaxValue)
return false;
return true;
}
private static uint GET_RESOURCE_ID(IntPtr value)
{
if (IS_INTRESOURCE(value) true)
return (uint) value;
throw new System.NotSupportedException("value is not an ID!");
}
private static string GET_RESOURCE_NAME(IntPtr value)
{
if (IS_INTRESOURCE(value) true)
return value.ToString();
return Marshal.PtrToStringUni((IntPtr) value);
}
[STAThread]
static void Main(string[] args)
{
IntPtr hMod = LoadLibraryEx(@”path to exe/dllfile”,
IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
if (EnumResourceNamesWithID(hMod, RT_ICON,
new EnumResNameDelegate(EnumRes), IntPtr.Zero) == false)
{
Console.WriteLine(“gle: {0}”, Marshal.GetLastWin32Error());
}
FreeLibrary(hMod);
}
static bool EnumRes(IntPtr hModule,
IntPtr lpszType,
IntPtr lpszName,
IntPtr lParam)
{
Console.WriteLine(“Type: {0}”, GET_RESOURCE_NAME(lpszType));
Console.WriteLine(“Name: {0}”, GET_RESOURCE_NAME(lpszName));
return true;
}
}
}
Posted 3 years, 3 months ago on November 9, 2004
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/26/
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/26/
Comments have now been turned off for this post