使用Win32 API列出存储在仅资源库(DLL)中的消息ID和符号名称

时间:2014-06-09 14:34:47

标签: c++ winapi visual-c++ dll

我们想列出资源专用库(DLL)中嵌入的消息的内容(键/值对)

资源库定义为指定的in MSDN

mc -s EventLogMsgs.mc
rc EventLogMsgs.rc
link /DLL /SUBSYSTEM:WINDOWS /NOENTRY /MACHINE:x86 EventLogMsgs.Res 

示例EventLogMsgs.mc可能是:

; // - Event categories -
; // Categories must be numbered consecutively starting at 1.
; // ********************************************************

MessageId=0x1
Severity=Success
SymbolicName=INSTALL_CATEGORY
Language=English
Installation
.

MessageId=0x2
Severity=Success
SymbolicName=QUERY_CATEGORY
Language=English
Database Query
.

...

我们尝试使用EnumResourceTypes()Win32 API,如下所示:

...
HMODULE hMod=NULL;
hMod = LoadLibraryA( "C:\\temp\\EventLogMsgs.dll" ); 
if (hMod != NULL) 
{
    EnumResourceTypes( hMod, (ENUMRESTYPEPROC)TypesCallback, 0) ;
    FreeLibrary(hMod);
}
...

BOOL WINAPI TypesCallback( HMODULE hModule, LPTSTR lpType, LONG lParam )
{
    char buffer[100];
    if ((ULONG)lpType & 0xFFFF0000) 
        sprintf( buffer, "%s\n", lpType); 
    else 
        sprintf(buffer, "%u\n", (USHORT)lpType); 

    cout << "Type: " << buffer << std::endl;

    EnumResourceNames( hModule, lpType, (ENUMRESNAMEPROC)NamesCallback, 0 );
    return true;
}

BOOL WINAPI NamesCallback( HMODULE hModule, LPCTSTR lpType, LPTSTR lpName, LONG lParam )
{
    char buffer[100];
    if ((ULONG)lpName & 0xFFFF0000) 
        sprintf(buffer,"%s\n", lpName); 
    else 
        sprintf(buffer, "%u\n",(USHORT)lpName); 
    cout << "Name: " << buffer << std::endl;
    return true;
}

结果是资源类型及其名称/标识符&#34;的高级列表,例如

...
Type: 11
Name: 1

Type: 16
Name: 1

Type: 24
Name: 2
...

11(RT_MESSAGETABLE)是消息表资源类型(See all resource types

理想情况下,我们希望列出 ALL 实际消息&#39;资源库中的符号名称和标识符。

由于

1 个答案:

答案 0 :(得分:4)

您已枚举模块中的资源,该资源会告诉您特定类型的每种资源的名称。完成后,您需要加载资源以检查其内容。在您的情况下,您需要名为RT_MESSAGETABLE的{​​{1}}类型的资源。

您现在需要使用1FindResourceLoadResource来获取指向消息表结构开头的指针。然后,您可以使用LockResource结构,然后依次MESSAGE_RESOURCE_DATAMESSAGE_RESOURCE_BLOCK来解压缩消息表的内容。这个Code Project article详细介绍了这个过程。

这是一个相当简单的C程序,它列举了您的消息表:

MESSAGE_RESOURCE_ENTRY

<强>输出

1, Installation
2, Database Query
3, Data Refresh
1000, My application message text, in English, for message id 1000, called from %1.
1002, My generic information message in English, for message id 1002.
1004, The update cycle is complete for %%5002.
5001, Sample Event Log
5002, SVC_UPDATE.EXE
-2147482647, My application message text, in English, for message id 1001, called from %1.
-2147482645, My generic warning message in English, for message id 1003, called from %1.
-2147482643, The refresh operation did not complete because the connection to server %1 could not be established.

请原谅我令人震惊的C. C和C ++都不是我熟悉的语言。但是,代码至少会告诉你如何提取你想要的信息。