LANG_ENGLISH 使用 NSIS 3.0 编译时未为 MUI 定义

LANG_ENGLISH undefined for MUI when compiling with NSIS 3.0

我刚从 NSIS 2.51 to NSIS 3.0, mainly because the new version supports Windows 10 升级。

对于我的安装程序,我使用 Modern User Interface (MUI). I make use of some custom pages. According to the documentation,我使用 MUI_HEADER_TEXT 宏在我的自定义页面函数中设置页眉上的文本,例如:

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

在安装程序脚本的末尾,我还添加了以下行:

!insertmacro MUI_LANGUAGE "English"

在 Windows 7 上,使用 NSIS 2.51(及更低版本)时编译时没有任何警告。但是,在使用 NSIS 3.0 进行编译时,LangString 行中的每一行都收到以下警告:

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

使用 NSIS 3.0 时似乎不再定义 LANG_ENGLISH。我可以通过将以下行添加到我的安装程序脚本来消除警告:

!define LANG_ENGLISH 1033

但是我应该怎么做才能以正确的方式为 NSIS 3.0 解决这个问题?


具有 4 个页面(2 个自定义页面)的最小、完整且可验证的示例:

!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 [=14=]
  ${If} [=14=] == error
    Abort
  ${EndIf}
  ${NSD_CreateLabel} 0 4u 100% 12u "Custom page one"
  Pop [=14=]
  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 [=14=]
  ${If} [=14=] == error
    Abort
  ${EndIf}
  ${NSD_CreateLabel} 0 4u 100% 12u "Custom page two"
  Pop [=14=]
  nsDialogs::Show
FunctionEnd

; Page 4.
!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"

我知道,在脚本末尾添加 MUI_LANGUAGE 行看起来很奇怪。但是,我不能将该行更早地放入脚本中,因为那样我会收到以下警告:

MUI_PAGE_* inserted after MUI_LANGUAGE [...]

如果我把 MUI_LANGUAGE 行放在 !insertmacro MUI_PAGE_WELCOME 之前,那么我也会收到以下警告:

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

在定义任何语言字符串之前需要插入宏。在您的语言定义之前和使用它们之前插入宏。

!insertmacro MUI_LANGUAGE "English"

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

据我所知,这在 NSIS 2 中没有任何不同——也许是 警告 是新的。

警告是 NSIS 3 中的新警告,但编译器行为未更改,LANG_ENGLISH 在 NSIS 2 中当时也未定义。

警告提示您正在发生的事情:当编译器到达您的 LangString 语句时 LANG_ENGLISH 尚未定义,因此编译器尝试将字符串 ${LANG_ENGLISH} 到一个数字并且失败并且数字转换函数 returns 0. 如果您查看 LangString 的文档,您会发现如果您将 0 作为语言 ID 传递,它将使用最后一个 used/loaded 语言。如果此时没有加载任何语言,它将保留默认语言,即英语。

LANG_xyz 定义是在使用 LoadLanguageFile 指令加载 xyz.nlf 时创建的。 MUI 在其 MUI_LANGUAGE 宏中调用 LoadLanguageFile,因此您的解决方案只是将 LangString 语句移动到 MUI_LANGUAGE 宏下方:

!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 [=10=]
${If} [=10=] == error
    Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "Hello world!"
Pop [=10=]
nsDialogs::Show
FunctionEnd