Search code examples
nsis

How to load the files based on the locale and generate the installer using NSIS?


My requirement is, I have specific files (Dlls, chms, etc) for each Locale (Language). I need to load those files based on the locale and generate the installer. And while uninstalling i should uninstall those files as well from the traget directory.

Here what i am doing is in .onInit function, using GetUserDefaultUILanguage() i am getting the locale and checking this locale and loading the files under this locale.

is it the correct way? Please provide any suggestions for this code.

And also do we need to use ;Pages section before the ;Languages section?

Because i am getting a warning to use ;Pages section before the ;Languages section when i am compiling.

Below is the code snippet i have written:

; LocaleDlls.nsi
;
;
; It will install LocaleDlls.nsi into a directory that the user selects.

;--------------------------------
!include LogicLib.nsh
 !include "MUI2.nsh"
; The name of the installer in the path C:\Program Files\LocaleDlls
Name "LocaleDlls"

; The file to write  in the path E:\Source\NULLSOFT\src
OutFile "LocaleDlls.exe"

; The default installation directory in the path C:\Program Files\LocaleDlls
InstallDir $PROGRAMFILES\LocaleDlls

; Registry key to check for directory (so if you install again, it will
; overwrite the old one automatically) It shows the path the path C:\Program Files\LocaleDlls
InstallDirRegKey HKLM "Software\NSIS_LocaleDlls" "Install_Dir"

; Request application privileges for Windows Vista
RequestExecutionLevel admin

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

; Pages

Page components
Page directory
Page instfiles

UninstPage uninstConfirm
UninstPage instfiles

;Pages

; Do we need to use PAGE macros before giving LANGUAGE as when compiling we are getting an error.
;--------------------------------

;Languages

  !insertmacro MUI_LANGUAGE "English" ; The first language is the default language
  !insertmacro MUI_LANGUAGE "PortugueseBR"

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

;Installer Functions

Function .onInit

 System::Call 'kernel32::GetUserDefaultUILanguage() i.r10'
 MessageBox MB_OK "Return value = $R0"
 
 StrCpy $Language ${LANG_PORTUGUESEBR}
 MessageBox MB_OK "Return value = $Language"
 
 ${If} $Language P= 1046

  MessageBox MB_OK "Current Locale is Portuguese... Loading Portuguese Files"
  ${EndIf}
  File E:\Source\NULLSOFT\src\EngPortuguese\Portuguese\AllowStandby.reg
  File E:\Source\NULLSOFT\src\EngPortuguese\Portuguese\Test.chm
  File E:\Source\NULLSOFT\src\EngPortuguese\Portuguese\Testdlg.dll
  File E:\Source\NULLSOFT\src\EngPortuguese\Portuguese\resource.dll
  
FunctionEnd

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


; The stuff to install
Section "LocaleDlls (required)"

  SectionIn RO

  ; Set output path to the installation directory. Here is the path C:\Program Files\LocaleDlls
  SetOutPath $INSTDIR

  ; Give the File path

  System::Call 'KERNEL32::AddDllDirectory(w "$INSTDIR")' ; Tell Windows we trust all .DLLs in this directory


  System::Call 'KERNEL32::LoadLibrary(t "$INSTDIR\testdlg.dll.dll")p.r8 ?e'
  Pop $7 ; Get ?e result
  ${IfThen} $8 P= 0 ${|} MessageBox MB_ICONSTOP "Failed to load pchuteres.dll, error $7" ${|}

  ${If} $8 P<> 0
  MessageBox MB_OK 'Successfully loaded "$INSTDIR\testdlg.dll.dll" @ $8'
  
  ${EndIf}
  
  
 ; Do the install

  ; Write the installation path into the registry
  WriteRegStr HKLM SOFTWARE\NSIS_DllTesting "Install_Dir" "$INSTDIR"

  ; Write the uninstall keys for Windows
  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LocaleDlls" "DisplayName" "NSIS LocaleDlls"
  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LocaleDlls" "UninstallString" '"$INSTDIR\uninstall.exe"'
  WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LocaleDlls" "NoModify" 1
  WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LocaleDlls" "NoRepair" 1
  WriteUninstaller "uninstall.exe"

SectionEnd

; Optional section (can be disabled by the user)
Section "Start Menu Shortcuts"

  CreateDirectory "$SMPROGRAMS\LocaleDlls"
  CreateShortcut "$SMPROGRAMS\LocaleDlls\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
  CreateShortcut "$SMPROGRAMS\LocaleDlls\LocaleDlls (MakeNSISW).lnk" "$INSTDIR\LocaleDlls.nsi" "" "$INSTDIR\LocaleDlls.nsi" 0

SectionEnd

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

; Uninstaller

Section "Uninstall"

  ; Remove registry keys
  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LocaleDlls"
  DeleteRegKey HKLM SOFTWARE\NSIS_LocaleDlls

  ; Remove files and uninstaller
  Delete $INSTDIR\LocaleDlls.nsi
  Delete $INSTDIR\uninstall.exe

  ; Remove shortcuts, if any
  Delete "$SMPROGRAMS\LocaleDlls\*.*"

  ; Remove directories used
  RMDir "$SMPROGRAMS\LocaleDlls"
  RMDir "$INSTDIR"

SectionEnd
;--------------------------------
;Uninstaller Functions

Function un.onInit

  !insertmacro MUI_UNGETLANGUAGE

FunctionEnd

Solution

  • You don't need to call GetUserDefaultUILanguage, NSIS calls GetUserDefaultUILanguage to try to set the default $language. If it cannot find a matching language, the first language specified in the .NSI is used. All of this happens before .onInit is called and you don't have to do anything. You can however change $language in .onInit if you are not happy with the language NSIS has chosen. You can also use !insertmacro MUI_LANGDLL_DISPLAY to display a language selection dialog.

    Pages need to be inserted before the language when using MUI because the language macro needs to know which strings are required by the pages. It is important that you use the MUI page macros MUI_PAGE_* and not the native page:

    !insertmacro MUI_PAGE_WELCOME
    Page Custom MyPage ; There is no MUI_PAGE_* macro for this
    !insertmacro MUI_PAGE_COMPONENTS
    !insertmacro MUI_PAGE_INSTFILES
    
    !insertmacro MUI_LANGUAGE "English" ; Must come after all MUI_PAGE_* macros.