Windows 使用NSIS 3.0编译时,MUI的语言未定义

Windows 使用NSIS 3.0编译时,MUI的语言未定义,windows,nsis,nsis-mui,Windows,Nsis,Nsis Mui,我刚从升级到,主要是因为新版本 对于我的安装程序,我正在使用。我使用一些自定义页面。根据,我正在使用MUI_HEADER_TEXT宏在自定义页面功能中设置页面标题上的文本,例如: [...] Page custom InstallType LangString PAGE_INSTALL_TYPE_TITLE ${LANG_ENGLISH} "Installation Type" LangString PAGE_INSTALL_TYPE_SUBTITLE ${LANG_ENGLISH} "Cho

我刚从升级到,主要是因为新版本

对于我的安装程序,我正在使用。我使用一些自定义页面。根据,我正在使用
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}”不是有效的语言id,使用的是语言id 1033![……]

在使用NSIS 3.0时,似乎不再定义语言。我可以通过在安装程序脚本中添加以下行来消除警告:

!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 $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"
我知道,脚本末尾有
MUI_语言
行看起来很奇怪。但是,我无法将该行较早地放入脚本中,因为这样我会得到以下警告:

MUI_页面*插入MUI_语言后[…]

如果我把
MUI\u语言
行放在
之前!insertmacro MUI_PAGE_WELCOME
,然后我还收到以下警告:

MUI_语言应插入MUI_[UN]页面*宏[…]之后


在定义任何语言字符串之前,需要插入宏。将宏插入到语言定义的正前方以及使用它们之前

!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中是新的,但编译器行为没有改变,在NSIS 2中也没有定义语言英语

警告提示您发生了什么:当编译器到达您的
LangString
语句时,LANG\u ENGLISH尚未定义,因此编译器尝试将字符串
${LANG\u ENGLISH}
转换为数字,但失败,数字转换函数返回0。如果查看
LangString
的文档,您会发现如果将0作为语言id传递,它将使用上次使用/加载的语言。如果此时未加载任何语言,则保留默认语言,即英语

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

!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

我试着按照你的建议重新排列命令。似乎我对所有命令的顺序有一个更大的误解,因为现在我得到:
MUI\u语言应该插入到MUI\u[UN]页面的宏之后。我已经将MUI定义直接放在了相应的页面函数前面,因此我将尝试将它们一起移动到
MUI\U语言
行之前。谢谢你,Anders。我把MUI
insertmacro
行、LangString
行和页面函数混在一起了。我按照你说的重新安排了一切,现在警告已经不见了。脚本仍在运行;)顺序并不是很严格,函数必须在MUI.nsh之后,因此如果您使用${LANG_XYZ},MUI_HEADER_文本存在,而LangString在MUI_语言之后……我明白了。我的主要问题是,我有三个自定义页面,并将属于一个页面的所有命令组合在一起。