windowsnsisnsis-mui

LANG_ENGLISH undefined for MUI when compiling with NSIS 3.0


I just upgraded from NSIS 2.51 to NSIS 3.0, mainly because the new version supports Windows 10.

For my installer I'm using the Modern User Interface (MUI). I make use of some custom pages. According to the documentation, I'm using the MUI_HEADER_TEXT macro to set the text on the page header in my custom page functions, for example:

[...]
Page custom InstallType

LangString PAGE_INSTALL_TYPE_TITLE ${LANG_ENGLISH} "Installation Type"
LangString PAGE_INSTALL_TYPE_SUBTITLE ${LANG_ENGLISH} "Choose installation type."

Function InstallType
    !insertmacro MUI_HEADER_TEXT $(PAGE_INSTALL_TYPE_TITLE) $(PAGE_INSTALL_TYPE_SUBTITLE)
    [...]

At end of my installer script I also added the following line:

!insertmacro MUI_LANGUAGE "English"

On Windows 7, this compiles without any warning when using NSIS 2.51 (and below). However, when compiling with NSIS 3.0, I get the following warning for each of the LangString lines:

"${LANG_ENGLISH}" is not a valid language id, using language id 1033! [...]

It seems that LANG_ENGLISH is no longer defined when using NSIS 3.0. I can get rid of the warning by adding the following line to my installer script:

!define LANG_ENGLISH 1033

But what am I supposed to do to fix this issue in the correct way for NSIS 3.0?


Minimal, complete, and verifiable example with 4 pages (2 custom pages):

!include "MUI2.nsh"

; Page 1.
!insertmacro MUI_PAGE_WELCOME

; Page 2.
Page custom InstallType

LangString PAGE_INSTALL_TYPE_TITLE ${LANG_ENGLISH} "Installation Type"
LangString PAGE_INSTALL_TYPE_SUBTITLE ${LANG_ENGLISH} "Choose installation type."

Function InstallType
  !insertmacro MUI_HEADER_TEXT $(PAGE_INSTALL_TYPE_TITLE) $(PAGE_INSTALL_TYPE_SUBTITLE)
  nsDialogs::Create /NOUNLOAD 1018
  Pop $0
  ${If} $0 == error
    Abort
  ${EndIf}
  ${NSD_CreateLabel} 0 4u 100% 12u "Custom page one"
  Pop $0
  nsDialogs::Show
FunctionEnd

; Page 3.
Page custom InstallVersion

LangString PAGE_VERSION_TITLE ${LANG_ENGLISH} "Version"
LangString PAGE_VERSION_SUBTITLE ${LANG_ENGLISH} "Choose version."

Function InstallVersion
  !insertmacro MUI_HEADER_TEXT $(PAGE_VERSION_TITLE) $(PAGE_VERSION_SUBTITLE)
  nsDialogs::Create /NOUNLOAD 1018
  Pop $0
  ${If} $0 == error
    Abort
  ${EndIf}
  ${NSD_CreateLabel} 0 4u 100% 12u "Custom page two"
  Pop $0
  nsDialogs::Show
FunctionEnd

; Page 4.
!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"

I know, having the MUI_LANGUAGE line at the end of the script looks strange. However, I can't put that line earlier into the script, because then I get the following warning:

MUI_PAGE_* inserted after MUI_LANGUAGE [...]

If I put the MUI_LANGUAGE line even before !insertmacro MUI_PAGE_WELCOME, then I also get the following warning:

MUI_LANGUAGE should be inserted after the MUI_[UN]PAGE_* macros [...]


Solution

  • The warning is new in NSIS 3 but the compiler behavior is unchanged, LANG_ENGLISH is not defined at that point in NSIS 2 either.

    The warning gives you a hint about what is going on: When the compiler gets to your LangString statements LANG_ENGLISH has not been defined yet so the compiler tries to convert the string ${LANG_ENGLISH} to a number and that fails and the number conversion function returns 0. If you look at the documentation for LangString you see that if you pass 0 as the language id it will use the last used/loaded language. If at this point no languages have been loaded it is left with the default language and that is English.

    The LANG_xyz defines are created by the LoadLanguageFile instruction when you use it to load xyz.nlf. MUI calls LoadLanguageFile inside its MUI_LANGUAGE macro so your solution is simply to move the LangString statements below the MUI_LANGUAGE macro:

    !include MUI2.nsh
    
    Page Custom MyPageCreate
    !insertmacro MUI_PAGE_INSTFILES
    !insertmacro MUI_LANGUAGE "English"
    
    LangString PAGE_INSTALL_TYPE_TITLE ${LANG_ENGLISH} "Installation Type"
    LangString PAGE_INSTALL_TYPE_SUBTITLE ${LANG_ENGLISH} "Choose installation type."
    
    Function MyPageCreate
    !insertmacro MUI_HEADER_TEXT $(PAGE_INSTALL_TYPE_TITLE) $(PAGE_INSTALL_TYPE_SUBTITLE)
    nsDialogs::Create 1018
    Pop $0
    ${If} $0 == error
        Abort
    ${EndIf}
    ${NSD_CreateLabel} 0 0 100% 12u "Hello world!"
    Pop $0
    nsDialogs::Show
    FunctionEnd