Reading Message Table resources from DLL files: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
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


API Functions used: