Reading Message Table resources from DLL files: Difference between revisions
CancerFace (talk | contribs) No edit summary |
(No difference)
|
Revision as of 19:56, 2 June 2006
| Author: CancerFace (talk, contrib) |
NSIS forum thread
Description
DLL files can contain Message Table resources with various strings that may be useful. How can these strings be extracted and used from within an NSIS installer? What if those strings are localized and contain unicode text? Using the FormatMessage API call one can get strings out of DLL files and use them directly
Usage
Call the macro from within your script passing the full path and name of the DLL file containing the Message Table, the ID of the string to get out as well as a variable that will accept the output:
Var "StringFromDLL" !insertmacro ReadStringFromDLL "<path_to_dll>\<filename.dll>" <String_ID> $StringFromDLL
Macro
If you want to get the string into a variable use the following macro:
!define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 !define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 !define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 !define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF !macro ReadStringFromDLL LIBRARY STRING_ID VAR System::Call 'kernel32::GetSystemDefaultLangID(i v)i .R0' System::Call 'kernel32::LoadLibraryExW(w "${LIBRARY}", i n, i 2) i .R1' StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE} IntOp $0 $0 + ${FORMAT_MESSAGE_ALLOCATE_BUFFER} IntOp $0 $0 + ${FORMAT_MESSAGE_IGNORE_INSERTS} IntOp $0 $0 + ${FORMAT_MESSAGE_MAX_WIDTH_MASK} System::Call 'kernel32::FormatMessageW(i r0, i R1, i ${STRING_ID}, i R0, *w .R2, i 0, i n) i .R3' System::Call 'kernel32::FreeLibrary(i R1)i .R8' StrCpy ${VAR} $R2 !macroend
If you want to get the string into a buffer and use it directly from the buffer in order to avoid placing unicode characters into an NSIS variable use the following macro:
!define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 !define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 !define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF !macro ReadStringFromDLL LIBRARY STRING_ID BUFFER_VAR System::Call 'kernel32::GetSystemDefaultLangID(i v)i .R0' System::Call 'kernel32::LoadLibraryExW(w "${LIBRARY}", i n, i 2) i .R1' StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE} IntOp $0 $0 + ${FORMAT_MESSAGE_IGNORE_INSERTS} IntOp $0 $0 + ${FORMAT_MESSAGE_MAX_WIDTH_MASK} System::Call '*(&w${NSIS_MAX_STRLEN})i.R2' System::Call 'kernel32::FormatMessageW(i r0, i R1, i ${STRING_ID}, i R0, i R2, i ${NSIS_MAX_STRLEN}, i n) i .R3' System::Call 'kernel32::FreeLibrary(i R1)i .R8' StrCpy ${BUFFER_VAR} $R2 !macroend
Now ${BUFFER_VAR} will be a pointer to an address containing the wide string. This address can be directly passed to other APIs without exporting the string to an NSIS variable.
Resources and Links
- NSIS forum thread
API Functions used: