NSIS change page subtitle - nsis

I want to support german and english for my setup. German is default.
I replaced MUI_TEXT_COMPONENTS_SUBTITLE for all languages.
For german my replaced subtitle is shown in the exe. But when i change the language in the exe (UMUI_PAGE_MULTILANGUAGE) to english, the standard title (from the nsis language files) is shown.
If i put english to default language my replaced title is shown.
What goes wrong here?
...
!define MUI_TEXT_COMPONENTS_SUBTITLE $(MUI_TEXT_COMPONENTS_SUBTITLE_MY)
...
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
!insertmacro UMUI_PAGE_MULTILANGUAGE
!insertmacro MUI_PAGE_COMPONENTS
...
!insertmacro MUI_LANGUAGE "German" ; first language is the default language
!insertmacro MUI_LANGUAGE "English"
LangString MUI_TEXT_COMPONENTS_SUBTITLE_MY ${LANG_GERMAN} "Wählen Sie die Komponenten aus, die Sie installieren möchten."
LangString MUI_TEXT_COMPONENTS_SUBTITLE_MY ${LANG_ENGLISH} "Choose which features you want to install."
...

MUI_TEXT_COMPONENTS_SUBTITLE is not documented anywhere, did you find it directly in the source files?
If you want to modify a single page then you should look at the "Page settings" part of the MUI readme:
!include MUI.nsh
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_HEADER_SUBTEXT $(MyComponentsSubtitle)
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_LANGUAGE "German" ; first language is the default language
!insertmacro MUI_LANGUAGE "English"
LangString MyComponentsSubtitle ${LANG_GERMAN} "TEST Wählen Sie die Komponenten aus, die Sie installieren möchten."
LangString MyComponentsSubtitle ${LANG_ENGLISH} "TEST Choose which features you want to install."
Function .onInit
!define MUI_LANGDLL_ALWAYSSHOW
!define MUI_LANGDLL_ALLLANGUAGES
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd

Related

How to set the Focus to a License Agreement Checkbox control using NSIS

I wanted to set the by default Focus to the "License Agreement" checkbox in the License Agreement Page using NSIS. And then the taborder should work.
Please help me how to set the focus?
Below is my code snippet:
!include LogicLib.nsh
!define MUI_TEXT_WELCOME_INFO_TITLE $(welcometitle)
!define MUI_TEXT_WELCOME_INFO_TEXT $(welcometext)
!insertmacro MUI_PAGE_WELCOME
!define MUI_LICENSEPAGE_CHECKBOX ""
!define MUI_INNERTEXT_LICENSE_BOTTOM ""
!define MUI_INNERTEXT_LICENSE_TOP ""
!define MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX ""
!define MUI_TEXT_LICENSE_TITLE $(licensetitle)
!define MUI_TEXT_LICENSE_SUBTITLE $(licensesubtitle)
!define MUI_LICENSEPAGE_CHECKBOX_TEXT $(licensecheckboxtext)
!insertmacro MUI_PAGE_LICENSE "C:\Program Files (x86)\NSIS\Docs\Modern UI 2\license.txt"
!define MUI_DIRECTORYPAGE_TEXT_TOP $(mydirtoptext)
!define MUI_TEXT_DIRECTORY_TITLE $(mydirtitle)
!define MUI_TEXT_DIRECTORY_SUBTITLE $(mydirsubtitle)
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_TEXT_FINISH_INFO_TITLE $(Finishpagetitle)
!define MUI_TEXT_FINISH_INFO_TEXT $(Finishpagesubtitle)
!define MUI_FINISHPAGE_RUN ""
!define MUI_FINISHPAGE_RUN_TEXT $(FinishonlineReg)
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_INSTFILES
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
; The stuff to install
Section "My TestApp (required)"
SectionEnd
The Windows UI guidelines says:
For keyboard navigation, tab order should flow in a logical order, generally from left to right, top to bottom.
but if you think you must force then you can do this:
!include WinMessages.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!define MUI_LICENSEPAGE_CHECKBOX ""
!define MUI_PAGE_CUSTOMFUNCTION_SHOW myForceLicenseFocus
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Function myForceLicenseFocus
!if ${MUI_SYSVERSION} >= 2.0
FindWindow $0 "BUTTON" "" $mui.LicensePage
!else
FindWindow $0 "#32770" "" $hWndParent
FindWindow $0 "BUTTON" "" $0
!endif
System::Call 'USER32::SetFocus(pr0)'
!define /ifndef WM_CHANGEUISTATE 0x127
System::Call 'USER32::PostMessage(pr0,i${WM_CHANGEUISTATE},p0x30002,p0)' ; This forces the checkbox to display the focus rectangle
System::Call 'USER32::SetWindowPos(pr0,p0,i,i,i,i,i0x13)' ; Change tab order
FunctionEnd

How to change MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT if exists two MUI_PAGE_INSTFILES

I have managed to customize the message shown in the title / subtitle after installation:
!define APP_NAME 'Test15'
name ${APP_NAME}
outfile '${APP_NAME}.exe'
showinstdetails show
InstallDir '$PROGRAMFILES\${APP_NAME}'
!include 'mui.nsh'
Var CompletedText
CompletedText $CompletedText
Var MUI_HeaderText
Var MUI_HeaderSubText
!define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "$MUI_HeaderText"
!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "$MUI_HeaderSubText"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section "One"
MessageBox MB_OK "Section One"
SectionEnd
Section -"Post"
;MessageBox MB_OK "Section Post"
StrCpy $CompletedText "My custom text"
StrCpy $MUI_HeaderText "My custom header text"
StrCpy $MUI_HeaderSubText "My custom header subText"
;MessageBox MB_OK "OUTING Section Post"
SectionEnd
My problem is that when I need to add a second part installation (it is a new mandatory requirement), and then not get modify / customize messages title / subtitle shown at the end:
!define APP_NAME 'Test15'
name ${APP_NAME}
outfile '${APP_NAME}.exe'
showinstdetails show
InstallDir '$PROGRAMFILES\${APP_NAME}'
!include 'mui.nsh'
Var CompletedText
CompletedText $CompletedText
Var MUI_HeaderText
Var MUI_HeaderSubText
!define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "$MUI_HeaderText"
!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "$MUI_HeaderSubText"
!insertmacro MUI_PAGE_INSTFILES
;This my second part instalation!!
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section "One"
MessageBox MB_OK "Section One"
SectionEnd
Section -"Post"
;MessageBox MB_OK "Section Post"
StrCpy $CompletedText "My custom text"
StrCpy $MUI_HeaderText "My custom header text"
StrCpy $MUI_HeaderSubText "My custom header subText"
;MessageBox MB_OK "OUTING Section Post"
SectionEnd
Now, the same message is always displayed at the end for Title/Subtitle: "Installation Complete" // "Setup was completed successfully.". Nevertheless, the 'completed' text value is modified successfully ("My custom text").
Please, can anyone help me?
Thanks in advance!
If you read the MUI documentation carefully you will find this in the "Page settings" section:
Page settings apply to a single page and should be set before inserting a page macro. The same settings can be used for installer and uninstaller pages. You have to repeat the setting if you want it to apply to multiple pages.
Only the defines listed under "Interface settings" are global.
!include MUI.nsh
!define MUI_PAGE_HEADER_TEXT "Install page #1"
!define MUI_PAGE_HEADER_SUBTEXT "Foo foo foo"
!define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "Did part 1"
!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "..."
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_HEADER_TEXT "Install page #2"
!define MUI_PAGE_HEADER_SUBTEXT "Bar bar bar!"
!define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "All done"
!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "ZZZzzz.."
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"

NSIS: Use selected language for MessageBox in .onInit (MUI2)

I try to get a localized message box in the .onInit method which fails with the following code:
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "German"
LangString Message ${LANG_ENGLISH} "This is a message."
LangString Message ${LANG_GERMAN} "Dies ist eine Nachricht"
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
MessageBox MB_OK "$(Message)"
FunctionEnd
The MessageBox always shows the same language string.
The Problem is, that the language is processed after the .onInit method.
A workaround for this could be to put the custom code from the .onInit method to the .onGUIInit method.
With MUI2 this is done as follows:
!define MUI_CUSTOMFUNCTION_GUIINIT myGuiInit
!include "MUI2.nsh"
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "German"
LangString Message ${LANG_ENGLISH} "This is a message."
LangString Message ${LANG_GERMAN} "Dies ist eine Nachricht"
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Function myGuiInit
MessageBox MB_OK "$(Message)"
FunctionEnd
Now the MessageBox should show the correctly localized message.

NSIS Change Header Image Based on Language Selection

I am using NSIS to create an installer. How can I change the header image (MUI_HEADERIMAGE_BITMAP) based on the users language selection at install?
!define MUI_HEADERIMAGE
!define MUI_CUSTOMFUNCTION_GUIINIT myGuiInit
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
...
!insertmacro MUI_LANGUAGE English
!insertmacro MUI_LANGUAGE Swedish
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Function myGUIInit
InitPluginsDir
${If} ${LANG_ENGLISH} = $Language
File "/oname=$PluginsDir\langspecifichdr.bmp" "${NSISDIR}\Contrib\Graphics\Header\orange.bmp"
${Else}
File "/oname=$PluginsDir\langspecifichdr.bmp" "${NSISDIR}\Contrib\Graphics\Header\win.bmp"
${EndIf}
SetBrandingImage /IMGID=1046 "$PluginsDir\langspecifichdr.bmp"
FunctionEnd

How to conditionally set first InstType in Component page

I want to conditionally set the first Installation type in Component page based on checking if some files already exists on the machine.
I've already tried two different approachs. 1) using SetCurInstType, 2) conditionally defining the InstType sequence order on the basis of a "file exist" check.
Both the approaches have been tested using an UDF function. This UDF function has been used, alternatively, as input for the MUI_PAGE_CUSTOMFUNCTION_LEAVE of MUI_PAGE_LICENSE and for the MUI_PAGE_CUSTOMFUNCTION_PRE of MUI_PAGE_COMPONENTS.
Both tests didn't work as expected
Approach 1)
InstType "Install (all)"
InstType "Install (minimal)"
!define USER_ALL_INST_TYPE 1
!define USER_MIN_INST_TYPE 2
!define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
!insertmacro MUI_PAGE_COMPONENTS
Section "1" Sec1
SectionIn ${USER_ALL_INST_TYPE} ${USER_MIN_INST_TYPE}
... other code
SectionEnd
Section "2" Sec2
SectionIn ${USER_ALL_INST_TYPE}
... other code
SectionEnd
Function SetInitInstType
IfFileExists "<file_path>" 0 endSetInitInstType
SetCurInstType ${USER_MIN_INST_TYPE}
endSetInitInstType:
FunctionEnd
Approach 2)
!define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
!insertmacro MUI_PAGE_COMPONENTS
Section "1" Sec1
SectionIn ${USER_ALL_INST_TYPE} ${USER_MIN_INST_TYPE}
... other code
SectionEnd
Section "2" Sec2
SectionIn ${USER_ALL_INST_TYPE}
... other code
SectionEnd
Function SetInitInstType
IfFileExists "<file_path>" 0 SetAllInstType
InstType "Install (minimal)"
InstType "Install (all)"
!define USER_MIN_INST_TYPE 1
!define USER_ALL_INST_TYPE 2
Goto endSetInitInstType
SetAllInstType:
InstType "Install (all)"
InstType "Install (minimal)"
!define USER_ALL_INST_TYPE 1
!define USER_MIN_INST_TYPE 2
endSetInitInstType:
FunctionEnd
After Condition check, if file existed, the expected result would be that the Install Mode ComboBox in Component page was initialized with the "Install (minimal)" option
The actual result is instead as follow:
Approach 1) --> All sections are disabled and the Install Mode ComboBox is initialized with the "Custom" option
Approach 2) --> I receive an error during script compiling
Section: "1" ->(Sec1)
SectionIn: Usage: SectionIn InstTypeIdx [InstTypeIdx [...]]
Error in script "<script_name>.nsi" on line XXX -- aborting creation process
Any suggestion would be really appreciated
Don't ask me why but SectionIn uses a different index system than all the other inst type functions.
Unlike SectionIn the index is zero based, which means the first install type's index is 0
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
!macro AddInstType name text
!define /IfNDef AddInstType_COUNTER 0
InstType "${text}"
!define INSTTYPE_${name}_IDX ${AddInstType_COUNTER} ; For SetCurInstType etc.
!define /ReDef /Math AddInstType_COUNTER ${AddInstType_COUNTER} + 1
!define INSTTYPE_${name}_SIN ${AddInstType_COUNTER} ; For SectionIn
!macroend
!insertmacro AddInstType ALL "Install (all)"
!insertmacro AddInstType MIN "Install (minimal)"
Section "1 (Both)" Sec1
SectionIn ${INSTTYPE_ALL_SIN} ${INSTTYPE_MIN_SIN}
SectionEnd
Section "2 (All only)" Sec2
SectionIn ${INSTTYPE_ALL_SIN}
SectionEnd
Function SetInitInstType
IfFileExists "$WinDir\Explorer.exe" 0 +2
SetCurInstType ${INSTTYPE_MIN_IDX}
FunctionEnd
Function .onInit
Call SetInitInstType ; In case installer is silent, force correct sections
FunctionEnd

Resources