Archive: bug with next button and multiple languages


bug with next button and multiple languages
Hi

I have an installer that supports both English and German. The localization to German works fine, except for the first button on the install welcome page, which says "next", ut the localized text on the welcome page says in German that in order to continue, you should press "weiter". Is this a bug or did I forget something - all the other buttons are localized correctly?


Hi, can't confirm this one. At least with NSIS 2.22 all buttons on my multilang installer are localized correctly.

Greez
Jens


Updated to NSIS 2.22 - still same problem...


Could you post a sample?

Cheers

Bruno


Hi again

The code is:


;--------------------------------
;Include Modern UI

!include "MUI.nsh"

;--------------------------------
;General

;Name and file
Name "foobar"
OutFile foobar.exe"
XPStyle on

;Default installation folder
InstallDir "$PROGRAMFILES\foobar"

;Get installation folder from registry if available
InstallDirRegKey HKCU "Software\foobar" ""


;--------------------------------
;Interface Configuration

!define MUI_ABORTWARNING
!define MUI_PAGE_CUSTOMFUNCTION_SHOW "FinishShow"
!define MUI_FINISHPAGE_RUN "$INSTDIR\foobar.exe"

;--------------------------------
;Definitions

!define SHCNE_ASSOCCHANGED 0x8000000
!define SHCNF_IDLIST 0
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar"
;--------------------------------

; Language Selection Dialog Settings
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"


;--------------------------------
;Pages

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE $(LicenseString)
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH


!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_LICENSE $(LicenseString)
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH

;--------------------------------
;Languages

!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "German"

;--------------------------------
;License Language String

LicenseLangString LicenseString ${LANG_ENGLISH} "P:\Products\foobar\Installer\Resources\en-License.rtf"
LicenseLangString LicenseString ${LANG_GERMAN} "P:\Products\foobar\Installer\Resources\de-License.rtf"

;--------------------------------
;Other Language strings
LangString foobarMissing ${LANG_ENGLISH} "This text is always shown when dialog box pops up"
LangString foobarMissing ${LANG_GERMAN} "This text is never shown (unless English language is removed and German is the only option)"

;--------------------------------

Function .onInit


;------------------Language selection dialog

Push ""
Push ${LANG_ENGLISH}
Push English
Push ${LANG_GERMAN}
Push German
Push A ; A means auto count languages
; for the auto count to work the first zempty push (Push "") must remain
LangDLL::LangDialog "Installer Language" "Please select the language of the installer"

Pop $LANGUAGE
StrCmp $LANGUAGE "cancel" 0 +2
Abort

MessageBox MB_YESNO $(foobarMissing) IDOK
Abort ; causes installer to quit.

FunctionEnd

;--------------------------------

Function FinishShow
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ;Hides the Back Button
GetDlgItem $0 $HWNDPARENT 2
ShowWindow $0 0 ;Hides the Cancel Button
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:Next"
FunctionEnd

;--------------------------------

;Installer Sections

Section "-foobar Section" Secfoobar

SetOutPath $INSTDIR\Assets
File /r "Assets\*.*"
SetOutPath $INSTDIR\Help
File /r "Help\*.*"
SetOutPath $INSTDIR
File "foobar.exe"
File "*.dll"

ReadRegStr $0 HKCU "Software\foobar" "version"

;Store installation folder
WriteRegStr HKCU "Software\foobar" "" $INSTDIR
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar" "DisplayName" "foobar"
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar" "UninstallString" "$INSTDIR\Uninstall.exe"

;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"

SectionEnd

;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Secfoobar} $(DESC_Secfoobar)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

;--------------------------------

Function un.onInit

!insertmacro MUI_UNGETLANGUAGE

FunctionEnd

;Uninstaller Section

Section "Uninstall"


;ADD YOUR OWN FILES HERE...
RMDir /r "$INSTDIR\Assets"
RMDir /r "$INSTDIR\Help"
Delete "$INSTDIR\foobar.exe"
Delete "$INSTDIR\*.dll"


Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"

DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar"
DeleteRegKey HKCU "Software\foobar"


SectionEnd


I have attached a screenshot of the (slightly modified) welcome page

Another issue is that for the message box code, it is always the text in English that is shown - not German.

Have a closer look to this code:

You're executing FinishShow before welcome.


;--------------------------------
;Interface Configuration

!define MUI_ABORTWARNING
!define MUI_PAGE_CUSTOMFUNCTION_SHOW "FinishShow"

And this sets the caption of the button as well...

Function FinishShow
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ;Hides the Back Button
GetDlgItem $0 $HWNDPARENT 2
ShowWindow $0 0 ;Hides the Cancel Button
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:Next"
FunctionEnd


Cheers

Bruno

Thanks Bruno

That solved the mystery. Now, how about when an alertbox pops up and it is only the English text that shows up, even when German has been selected


You're welcome!

You have to use

;Interface Configuration
!define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit ; <---
!define MUI_ABORTWARNING

Function onGUIInit
MessageBox MB_YESNO $(foobarMissing) IDOK
FunctionEnd

Here's the reason:

http://forums.winamp.com/showthread....50#post2068050

And: I'd recommend using the MUI_LANGDLL...
Have a look at Section 5 in
http://nsis.sourceforge.net/Docs/Mod...UI/Readme.html
and of course at the MultiLanguage.nsi in the Examples folder.

Cheers

Bruno


Ok

But in my .onInit function i make several checks, so several alert boxes might pop up, each with their own text. How do I do that?


That's ok. Just put it into the onGUIInit.

Function onGUIInit
:
:
MessageBox MB_YESNO $(foobarMissing) IDOK
:
:
FunctionEnd


I forgot to mention that the text displayed in the message box is localized, so it has to be selected dependant on the language selected. Also, some of the boxes are yes|no boxes, where i need to take action dependant on the user input (i.e. jump to different labels). This seems not to be possible.


It's possible. Localising is possible as well in the onGUIInit function. Did you define the function?

!define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit ; <---


Yes i did.

I get a compile error that it cannot resolve the _continue label. the code now looks like:


;--------------------------------
;Include Modern UI

!include "MUI.nsh"

;--------------------------------
;General

;Name and file
Name "foobar"
OutFile foobar.exe"
XPStyle on

;Default installation folder
InstallDir "$PROGRAMFILES\foobar"

;Get installation folder from registry if available
InstallDirRegKey HKCU "Software\foobar" ""


;--------------------------------
;Interface Configuration

!define MUI_ABORTWARNING
!define MUI_PAGE_CUSTOMFUNCTION_SHOW "FinishShow"
!define MUI_FINISHPAGE_RUN "$INSTDIR\foobar.exe"
!define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit

;--------------------------------
;Definitions

!define SHCNE_ASSOCCHANGED 0x8000000
!define SHCNF_IDLIST 0
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar"
;--------------------------------

; Language Selection Dialog Settings
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"


;--------------------------------
;Pages

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE $(LicenseString)
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH


!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_LICENSE $(LicenseString)
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH

;--------------------------------
;Languages

!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "German"

;--------------------------------
;License Language String

LicenseLangString LicenseString ${LANG_ENGLISH} "P:\Products\foobar\Installer\Resources\en-License.rtf"
LicenseLangString LicenseString ${LANG_GERMAN} "P:\Products\foobar\Installer\Resources\de-License.rtf"

;--------------------------------
;Other Language strings
LangString InstallerAlreadyRunning ${LANG_ENGLISH} "The installer is already running."
LangString InstallerAlreadyRunning ${LANG_GERMAN} "not shown in german"

LangString InstallingSameVersion ${LANG_ENGLISH} "You are installing the same version of foobar as already installed. Continue?"
LangString InstallingSameVersion ${LANG_GERMAN} "not shown in german"

LangString InstallingOlderVersion ${LANG_ENGLISH} "You cannot install an older version of foobar!"
LangString InstallingOlderVersion ${LANG_GERMAN} "not shown in german"

;--------------------------------

Function .onInit


;------------------Language selection dialog

Push ""
Push ${LANG_ENGLISH}
Push English
Push ${LANG_GERMAN}
Push German
Push A ; A means auto count languages
; for the auto count to work the first zempty push (Push "") must remain
LangDLL::LangDialog "Installer Language" "Please select the language of the installer"

Pop $LANGUAGE
StrCmp $LANGUAGE "cancel" 0 +2
Abort

;------------------ check if installer is already running
_checkInstaller:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "foobar") i .r1 ?e'
Pop $R0

StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONINFORMATION $(InstallerAlreadyRunning)
Abort

;------------------ check for version

ReadRegStr $0 HKCU "Software\foobar" "major"
ReadRegStr $1 HKCU "Software\foobar" "minor"
ReadRegStr $2 HKCU "Software\foobar" "build"

IntCmp $0 $Current_major _sameMajor _continue _older

_sameMajor:
IntCmp $1 $Current_minor _sameMinor _continue _older

_sameMinor:
IntCmp $2 $Current_build _sameBuild _continue _older

_sameBuild:
MessageBox MB_YESNO $(InstallingSameVersion) IDYES _continue
Abort ; causes installer to quit.

_older:
MessageBox MB_OK $(InstallingOlderVersion) IDOK _abort ; causes installer to quit.
goto _abort

_abort:
Abort

_continue:

.....more code
FunctionEnd

;--------------------------------

Function onGUIInit

MessageBox MB_OK|MB_ICONINFORMATION $(InstallerAlreadyRunning) IDOK
MessageBox MB_YESNO $(InstallingSameVersion) IDYES _continue
MessageBox MB_YESNO $(InstallingOlderVersion) IDOK _abort

FunctionEnd

;--------------------------------

Function FinishShow
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ;Hides the Back Button
GetDlgItem $0 $HWNDPARENT 2
ShowWindow $0 0 ;Hides the Cancel Button
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:Next"
FunctionEnd

;--------------------------------

;Installer Sections

Section "-foobar Section" Secfoobar

SetOutPath $INSTDIR\Assets
File /r "Assets\*.*"
SetOutPath $INSTDIR\Help
File /r "Help\*.*"
SetOutPath $INSTDIR
File "foobar.exe"
File "*.dll"

ReadRegStr $0 HKCU "Software\foobar" "version"

;Store installation folder
WriteRegStr HKCU "Software\foobar" "" $INSTDIR
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar" "DisplayName" "foobar"
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar" "UninstallString" "$INSTDIR\Uninstall.exe"

;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"

SectionEnd

;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Secfoobar} $(DESC_Secfoobar)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

;--------------------------------

Function un.onInit

!insertmacro MUI_UNGETLANGUAGE

FunctionEnd

;Uninstaller Section

Section "Uninstall"


;ADD YOUR OWN FILES HERE...
RMDir /r "$INSTDIR\Assets"
RMDir /r "$INSTDIR\Help"
Delete "$INSTDIR\foobar.exe"
Delete "$INSTDIR\*.dll"


Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"

DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\foobar"
DeleteRegKey HKCU "Software\foobar"


SectionEnd

Although it's not written explicitly I'd suggest using letters for labels.

http://nsis.sourceforge.net/Docs/Chapter4.html#4.3

Put all the language related stuff into onGUIInit. (Except the code for the dialog box...)


Do you mean take the lines:


LangString InstallerAlreadyRunning ${LANG_ENGLISH} "The installer is already running."
LangString InstallerAlreadyRunning ${LANG_GERMAN} "not shown in german"

LangString InstallingSameVersion ${LANG_ENGLISH} "You are installing the same version of foobar as already installed. Continue?"
LangString InstallingSameVersion ${LANG_GERMAN} "not shown in german"

LangString InstallingOlderVersion ${LANG_ENGLISH} "You cannot install an older version of foobar!"
LangString InstallingOlderVersion ${LANG_GERMAN} "not shown in german"


and put into onGUIInit?

Ahm, I thought these lines. If you do this, your language variables are correctly shown. But you have to pay attention to the /S (Silent) switch. Because if someone sets this, onGUIInit is not executed. So you should prevent people from doing this.

onInit:


IfSilent 0 +3
MessageBOX MB_OK "not possible... bye!"
Quit

onGUIInit

;------------------ check if installer is already running
_checkInstaller:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "foobar") i .r1 ?e'
Pop $R0

StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONINFORMATION $(InstallerAlreadyRunning)
Abort

;------------------ check for version

ReadRegStr $0 HKCU "Software\foobar" "major"
ReadRegStr $1 HKCU "Software\foobar" "minor"
ReadRegStr $2 HKCU "Software\foobar" "build"

IntCmp $0 $Current_major _sameMajor _continue _older

_sameMajor:
IntCmp $1 $Current_minor _sameMinor _continue _older

_sameMinor:
IntCmp $2 $Current_build _sameBuild _continue _older

_sameBuild:
MessageBox MB_YESNO $(InstallingSameVersion) IDYES _continue
Abort ; causes installer to quit.

_older:
MessageBox MB_OK $(InstallingOlderVersion) IDOK _abort ; causes installer to quit.
goto _abort

_abort:
Abort

_continue:

; .....more code


Have a nice day!

Cheers

Bruno

Hi Bruno

Thanks for the help so far. However, I get a compile error when trying to put in the .onGUIInit function. I define the function like you said as:


!define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit


and the function itself is defined as:

Function .onGUIInit
;------------------Language selection dialog
!insertmacro MUI_LANGDLL_DISPLAY

;------------------ check if installer is already running
_checkInstaller:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "foobar") i .r1 ?e'
Pop $R0

StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONINFORMATION $(InstallerAlreadyRunning)
Abort

;------------------ check for version

ReadRegStr $0 HKCU "Software\foobar" "major"
ReadRegStr $1 HKCU "Software\foobar" "minor"
ReadRegStr $2 HKCU "Software\foobar" "build"

IntCmp $0 $Current_major _sameMajor _continue _older

_sameMajor:
IntCmp $1 $Current_minor _sameMinor _continue _older

_sameMinor:
IntCmp $2 $Current_build _sameBuild _continue _older

_sameBuild:
MessageBox MB_YESNO $(InstallingSameVersion) IDYES _continue
Abort ; causes installer to quit.

_older:
MessageBox MB_OK $(InstallingOlderVersion) IDOK _abort ; causes installer to quit.
goto _abort

_abort:
Abort

_continue:

.....more code
FunctionEnd



The compile error I get is:

Function: ".onGUIInit"
Error: Function named ".onGUIInit" already exists.

Hi again

I found the error myself - I should use onGUIInit and not .onGUIInit and the language selection should happen in .onInit. It works now, so thanks for the help Bruno.
Cheers