LANG_ENGLISH undefined for MUI when compiling with NSIS 3.0
Asked Answered
A

2

6

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 [...]

Armijo answered 10/8, 2016 at 16:40 Comment(0)
A
8

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
Astrogation answered 12/8, 2016 at 18:18 Comment(3)
Thank you, Anders. I had mixed up the MUI insertmacro lines, the LangString lines, and the page functions. I rearranged everything as you said and now the warning is gone. And the script is still working ;)Armijo
The order is not really that strict, the function has to come after MUI.nsh so MUI_HEADER_TEXT exists and LangString after MUI_LANGUAGE if you are using ${LANG_XYZ}...Astrogation
I see. My main problem was that I have three custom pages and had grouped together all commands that belong to a page.Armijo
T
2

The macro needs to be inserted before you're defining any language strings. Insert the macro right before your language definitions and before the using them.

!insertmacro MUI_LANGUAGE "English"

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

As far as I remember, this isn't any different in NSIS 2 – maybe it's the warning that is new.

Twyla answered 11/8, 2016 at 11:17 Comment(1)
I tried to reorder the commands as you suggested. It seems that I have a larger misunderstanding on how order all commands, because now I get: MUI_LANGUAGE should be inserted after the MUI_[UN]PAGE_* macros. I had put the MUI defines directly in front of the corresponding page functions, so I will try to move them together before the MUI_LANGUAGE line next.Armijo

© 2022 - 2024 — McMap. All rights reserved.