gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 01:52:43 27 4
gpt4 key购买 nike

我们想列出嵌入在纯资源库 (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;
}

结果是资源类型及其“名称/标识符”的高级列表,例如,

...
Type: 11
Name: 1

Type: 16
Name: 1

Type: 24
Name: 2
...

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

理想情况下,我们希望在资源库中列出所有 实际消息的符号名称和标识符。

谢谢

最佳答案

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

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

这是一个枚举消息表的相当简单的 C 程序:

#include <windows.h>
#include <stdio.h>

int ProcessBlock(MESSAGE_RESOURCE_DATA* data, MESSAGE_RESOURCE_BLOCK* block)
{
MESSAGE_RESOURCE_ENTRY* entry = (MESSAGE_RESOURCE_ENTRY*) ((unsigned char*)data + block->OffsetToEntries);
for (DWORD id = block->LowId; id <= block->HighId; id++)
{
if (entry->Flags == 0x0001) // wide char
printf("%d, %ls", id, entry->Text);
else if (entry->Flags == 0x0000) // ANSI
printf("%d, %s", id, entry->Text);
entry = (MESSAGE_RESOURCE_ENTRY*) ((unsigned char*)entry + entry->Length);
}
return 1;
}

int main(void)
{
HMODULE hMod = LoadLibrary("C:\\desktop\\EventLogMsgs.dll");
if (hMod == NULL) return 1;

HRSRC hRsrc = FindResource(hMod, MAKEINTRESOURCE(1), RT_MESSAGETABLE);
if (hRsrc == NULL) return 1;

HGLOBAL hGlobal = LoadResource(hMod, hRsrc);
if (hGlobal == NULL) return 1;

MESSAGE_RESOURCE_DATA* data = (MESSAGE_RESOURCE_DATA*)LockResource(hGlobal);
if (data == NULL) return 1;

for (DWORD block = 0; block < data->NumberOfBlocks; block++)
if (!ProcessBlock(data, &data->Blocks[block]))
return 1;

return 0;
}

输出

1, Installation2, Database Query3, Data Refresh1000, 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 Log5002, 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++ 都不是我能熟练掌握的语言。但是,代码至少会告诉你如何提取你想要的信息。

关于c++ - 使用 Win32 API 列出存储在纯资源库 (DLL) 中的消息 ID 和符号名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24122552/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com