Click here to Skip to main content
15,885,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I tried using Resource Hacker to open exlorer.exe and I can see there are some resource types such as MUI, IMAGE, ICON ...

But trying enumerating resource types using some Win32 API functions didn't succeed, It enumerated only 1 resource type called MUI (the first one in the resource types list), here is my code:

C#
public Form1()
        {
            InitializeComponent();
            //obtain the handle of the Explorer.exe, just a copy of it)
            IntPtr hExplorer = LoadLibrary("C:\\explorer.exe");
            //Start enumerating resource types
            EnumResourceTypes(hExplorer, new EnumResTypeProc(EnumResTypeProcInstance), 0);
        }
        [DllImport("kernel32")]
        private static extern IntPtr LoadLibrary(string filename);
        [DllImport("kernel32")]
        private static extern int EnumResourceTypes(IntPtr hModule, EnumResTypeProc enumResTypeProc, int param);
        private delegate bool EnumResTypeProc(IntPtr hModule, string type, int param);
        private bool EnumResTypeProcInstance(IntPtr hModule, string type, int param)
        {
            MessageBox.Show(type);
            return true;//As I read from some source, this is for continuing enumerating.
        }


The code works without exception but the MessageBox pops up only 1 time showing "MUI", I think it should pops up many times enough to show all the resouce types in explorer.exe (as I can see with Resource Hacker).

Could you please show me some thing wrong in my code making it not work as I expected?

Your help would be highly appreciated!
Thanks!
Posted
Comments
supernorb 7-Feb-13 5:48am    
After hours waiting, not just a comment??? This life is so boring, at least to me...
CHill60 7-Feb-13 10:11am    
Try replacing <pre>string type</pre> with <pre>int type</pre>. It's an LPTSTR that's required

1 solution

Replace
C#
private delegate bool EnumResTypeProc(IntPtr hModule, string type, int param);
private bool EnumResTypeProcInstance(IntPtr hModule, string type, int param)

with
C#
private delegate bool EnumResTypeProc(IntPtr hModule, int type, int param);
private bool EnumResTypeProcInstance(IntPtr hModule, int type, int param)

and you'll have to show type.ToString()

I've seen comments elsewhere that suggest use of a MessageBox.Show() can "upset" callback methods. Hasn't impacted in this case, but you might be better off with
C#
using System.Diagnostics;
...
Debug.Print(type.ToString())


[Edit]
Instead of type.ToString() try this Debug.Print(type.ToString() + " " + EnumResTypeName(type));
where the new function is
C#
private string EnumResTypeName(int Type)
{
    string ret;
    switch (Type)
    {
        case RT_ACCELERATOR:
            ret = "RT_ACCELERATOR";
            break;
        case RT_ANICURSOR:
            ret = "RT_ANICURSOR";
            break;
        case RT_ANIICON:
            ret = "RT_ANIICON";
            break;
        case RT_BITMAP:
            ret = "RT_BITMAP";
            break;
        case RT_CURSOR:
            ret = "RT_CURSOR";
            break;
        case RT_DIALOG:
            ret = "RT_DIALOG";
            break;
        case RT_DLGINCLUDE:
            ret = "RT_DLGINCLUDE";
            break;
        case RT_FONT:
            ret = "RT_FONT";
            break;
        case RT_FONTDIR:
            ret = "RT_FONTDIR";
            break;
        case RT_GROUP_CURSOR:
            ret = "RT_GROUP_CURSOR";
            break;
        case RT_GROUP_ICON:
            ret = "RT_GROUP_ICON";
            break;
        case RT_HTML:
            ret = "RT_HTML";
            break;
        case RT_ICON:
            ret = "RT_ICON";
            break;
        case RT_MANIFEST:
            ret = "RT_MANIFEST";
            break;
        case RT_MENU:
            ret = "RT_MENU";
            break;
        case RT_MESSAGETABLE:
            ret = "RT_MESSAGETABLE";
            break;
        case RT_PLUGPLAY:
            ret = "RT_PLUGPLAY";
            break;
        case RT_RCDATA:
            ret = "RT_RCDATA";
            break;
        case RT_STRING:
            ret = "RT_STRING";
            break;
        case RT_VERSION:
            ret = "RT_VERSION";
            break;
        case RT_VXD:
            ret = "RT_VXD";
            break;
        case RT_DLGINIT:
            ret = "RT_DLGINIT";
            break;
        case RT_TOOLBAR:
            ret = "RT_TOOLBAR";
            break;
        default:
            ret = "Unknown Type";
            break;
    }
    return ret;
}


which uses the constants
C#
const int RT_ACCELERATOR = 9; //Accelerator table.
const int RT_ANICURSOR = 21; //Animated cursor.
const int RT_ANIICON = 22; //Animated icon.
const int RT_BITMAP = 2; //Bitmap resource.
const int RT_CURSOR = 1; //Hardware-dependent cursor resource.
const int RT_DIALOG = 5; //Dialog box.
const int RT_DLGINCLUDE = 17; //Allows
const int RT_FONT = 8; //Font resource.
const int RT_FONTDIR = 7; //Font directory resource.
const int RT_GROUP_CURSOR = ((RT_CURSOR) + 11); //Hardware-independent cursor resource.
const int RT_GROUP_ICON = ((RT_ICON) + 11); //Hardware-independent icon resource.
const int RT_HTML = 23; //HTML resource.
const int RT_ICON = 3; //Hardware-dependent icon resource.
const int RT_MANIFEST = 24; //Side-by-Side Assembly Manifest.
const int RT_MENU = 4; //Menu resource.
const int RT_MESSAGETABLE = 11; //Message-table entry.
const int RT_PLUGPLAY = 19; //Plug and Play resource.
const int RT_RCDATA = 10; //Application-defined resource (raw data).
const int RT_STRING = 6; //String-table entry.
const int RT_VERSION = 16; //Version resource.
const int RT_VXD = 20; //
const int RT_DLGINIT = 240;
const int RT_TOOLBAR = 241;


I know there's a tidier way of doing this but can't think of it at the moment.
If you actually want the names of the resources themsselves (e.g. icon names) then you need to feed the type into EnumResourceNames - have a look at this blog[^]
 
Share this answer
 
v2
Comments
supernorb 8-Feb-13 21:13pm    
It seems that you tested the code and it worked well? But I did replace those lines of code as you suggested and the result is 16 shown instead of 'MUI', only 16 shown, (hahaa), why is this? I think the param type is type of string, not int, Could you please review your code to find any other things different from my code (except what you suggested to be modified). Thanks! =)
CHill60 9-Feb-13 16:34pm    
I checked the API here http://www.codegod.com/Win32APIViewer.aspx?api=EnumResourceTypes. But also found this article http://dotnet.dzone.com/articles/loading-icons-winapi-way-c. In the meantime I'm adding some stuff to the solution ... not the tidiest but it's a bit late here at the moment!
supernorb 11-Feb-13 12:04pm    
Thank you for your update, however I still have some things unclear here, first If you open any exe file using Resource Hacker, you can see there is a Resource type MUI right at the first position of the resource types list, I can't see any MUI type in the types collection in the code above, this MUI type is achieved only by declaring 'type' as string, if declaring it as int (you suggested this), it showed 16 and matching this value to all resource type constants of int (in your updated code), the corresponding resource type is RT_VERSION, secondly, even when I use your 'converter' function between integer numbers and the corresponding Resouce type strings, the result will be only 1 resource type shown (by using your updated code, it is RT_VERSION instead of MUI or 16, and this is the hardest one I can't understand??? It should show me at least some resource types like resource hacker can extracts, I have even tried using a List<string> to add all the resource types found and show the types later, but the result is still only 1 type. I hope you would continue helping me by focusing on the second. Thank you so much for your effort!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900