NSIS – Localization Part I
Posted by admin on December 1st, 2007This week I have been searching a lot on localization in NSIS. Normally we just used the standard dialogs with a default language depending on where the cd-rom would be used. If we made a cd-rom for French-speaking part of Belguim, then the language was French. If the cd-rom was for Dutch-speaking part of Belguim, the language was Dutch. So no choice could be made at the beginning. If something wasn't spelled right, we went changing some things in the standard language files in the NSIS folder under Program Files. However, with a new update, these files get overwritten, so don't know how to do this good...
A new application that we are creating requires the choice of multiple languages and custom dialogs that need to be localized. I haven't figured it out all, but I'm getting to know more and more about NSIS. I guess this is a problem with all Open Source projects. The people who are creating the Open Source project are so familiar with the project that they don't seem to be able to explain something on the level of a user who's not constantly working with the technology. Most of those people are not stupid, but most of the times there are no simple tutorials available. As a result, you go and ask the most stupid questions on a forum. But it's only months later that you realize that the question was stupid.
I first tried to get the multiple languages working. The wizard of the NSISEclipsePlugin was usefull, however, this wizard generates a script that is failing on a few issues.
First you need to import the files for the languages you want to include.
-
!insertmacro MUI_LANGUAGE Dutch
-
!insertmacro MUI_LANGUAGE French
-
!insertmacro MUI_LANGUAGE English
-
!insertmacro MUI_LANGUAGE German
It took a while until I realised that inserting a macro basically means that you are inserting code out of a nsh file you previously imported. The macro MUI_LANGUAGE obviously comes out of the MUI.nsh file which was previously imported (!include MUI.nsh). If you open MUI.nsh you'll see
-
!include "${NSISDIR}\Contrib\Modern UI\System.nsh"
If you open System.nsh and search for MUI_LANGUAGE you'll find the macro
-
!macro MUI_LANGUAGE LANGUAGE
-
-
;Include a language
-
-
!verbose push
-
!verbose ${MUI_VERBOSE}
-
-
!insertmacro MUI_INSERT
-
-
LoadLanguageFile "${NSISDIR}\Contrib\Language files\${LANGUAGE}.nlf"
-
!insertmacro LANGFILE_INCLUDE "${NSISDIR}\Contrib\Language files\${LANGUAGE}.nsh"
-
-
!ifndef MUI_LANGDLL_LANGUAGES
-
!define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' "
-
!define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' "
-
!else
-
!ifdef MUI_LANGDLL_LANGUAGES_TEMP
-
!undef MUI_LANGDLL_LANGUAGES_TEMP
-
!endif
-
!define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}"
-
!undef MUI_LANGDLL_LANGUAGES
-
-
!ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP
-
!undef MUI_LANGDLL_LANGUAGES_CP_TEMP
-
!endif
-
!define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}"
-
!undef MUI_LANGDLL_LANGUAGES_CP
-
-
!define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}"
-
!define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}"
-
!endif
-
-
!verbose pop
-
-
!macroend
So this block of code is inserted where you had !insertmacro MUI_LANGUAGE Dutch. I haven't gone though this code, but it loads the nlf language file and inserts the nsh language script. It basically means that instead of using the macro's you could just put all of the code in your script, resulting however in a script the size of a book. I haven't had time to figure out how all these variables of several language files are managed and how NSIS knows depending on the chosen language where to look for the correct variables. But I will look into it.
Now, to display the choice of language in the beginning you need to put some defines at the beginning of the script that will be used by some macro's.
-
#Language defines
-
!define MUI_LANGDLL_REGISTRY_ROOT HKLM
-
!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY}
-
!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage
Then insert the macro
-
# Language macro's
-
!insertmacro MUI_RESERVEFILE_LANGDLL
This looks like
-
!macro MUI_RESERVEFILE_LANGDLL
-
-
!verbose push
-
!verbose ${MUI_VERBOSE}
-
-
ReserveFile "${NSISDIR}\Plugins\LangDLL.dll"
-
-
!verbose pop
-
-
!macroend
Then in the .onInit function we'll insert another macro
-
!insertmacro MUI_LANGDLL_DISPLAY
which looks like
-
!macro MUI_LANGDLL_DISPLAY
-
-
!verbose push
-
!verbose ${MUI_VERBOSE}
-
-
!insertmacro MUI_DEFAULT MUI_LANGDLL_WINDOWTITLE "Installer Language"
-
!insertmacro MUI_DEFAULT MUI_LANGDLL_INFO "Please select a language."
-
-
!ifdef MUI_LANGDLL_REGISTRY_ROOT & MUI_LANGDLL_REGISTRY_KEY & MUI_LANGDLL_REGISTRY_VALUENAME
-
-
ReadRegStr $MUI_TEMP1 "${MUI_LANGDLL_REGISTRY_ROOT}" "${MUI_LANGDLL_REGISTRY_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
-
StrCmp $MUI_TEMP1 "" mui.langdll_show
-
StrCpy $LANGUAGE $MUI_TEMP1
-
!ifndef MUI_LANGDLL_ALWAYSSHOW
-
Goto mui.langdll_done
-
!endif
-
mui.langdll_show:
-
-
!endif
-
-
!ifdef NSIS_CONFIG_SILENT_SUPPORT
-
IfSilent mui.langdll_done
-
!endif
-
-
!ifdef MUI_LANGDLL_ALLLANGUAGES
-
LangDLL::LangDialog "${MUI_LANGDLL_WINDOWTITLE}" "${MUI_LANGDLL_INFO}" A ${MUI_LANGDLL_LANGUAGES} ""
-
!else
-
LangDLL::LangDialog "${MUI_LANGDLL_WINDOWTITLE}" "${MUI_LANGDLL_INFO}" AC ${MUI_LANGDLL_LANGUAGES_CP} ""
-
!endif
-
-
Pop $LANGUAGE
-
StrCmp $LANGUAGE "cancel" 0 +2
-
Abort
-
-
!ifdef NSIS_CONFIG_SILENT_SUPPORT
-
mui.langdll_done:
-
!else ifdef MUI_LANGDLL_REGISTRY_ROOT & MUI_LANGDLL_REGISTRY_KEY & MUI_LANGDLL_REGISTRY_VALUENAME
-
mui.langdll_done:
-
!endif
-
-
!verbose pop
-
-
!macroend
I'll try to explain this more in later posts, but this gives ou an idea what these macro's are. Actually you don't need to know how they work, but if something goes wrong, or if you want to do custom things, it's really necessary to understand some things.
Recent Comments