;2024-04-14 ;Define installer compression method and level SetCompressor /SOLID LZMA ;Activate CRC check CRCCheck on ;-------------------------------------------------------------------------------- ;Constants !define PRODUCT_YEAR "2024" !define PRODUCT_VERSION "${PRODUCT_YEAR}.04.14.0" !define PRODUCT_UUID "1e626553-03f9-47e1-a0cd-858e8effe76e" ;Change for each new product !define PRODUCT_BRAND "Zogg" !define PRODUCT_NAME "Mods" !define PRODUCT_TAG ZoggMods !define PRODUCT_URL "https://mods.zogg.fr" !define PRODUCT_INSTALLER "mods.exe" !define PRODUCT_UNINSTALLER "uninstall.exe" !define PRODUCT_DESCRIPTION "PolyMC ${PRODUCT_NAME} for ${PRODUCT_BRAND} Minecraft server" !define PRODUCT_TITLE "${PRODUCT_BRAND} ${PRODUCT_NAME}" !define PRODUCT_COMPONENTS "Fabric mods, Ressources Packs & Shaders" !define PRODUCT_DEST "$LOCALAPPDATA" !define PRODUCT_SMDIR "NSIS:StartMenuDir" !define PRODUCT_REGROOT HKCU !define PRODUCT_REGPATH "${PRODUCT_BRAND}\${PRODUCT_NAME}" !define PRODUCT_REG_INSTDIR "NSIS:InstallDir" !define UNINSTALL_REGROOT HKLM !define UNINSTALL_REGPATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_REGPATH}" !define POLYMC_REGKEY "Software\PolyMC" !define POLYMC_REGVAR "InstallDir" ;-------------------------------------------------------------------------------- ;Modern UI !include "MUI2.nsh" !include "Library.nsh" !include "x64.nsh" !include "WinVer.nsh" ;-------------------------------------------------------------------------------- ;Macros !macro UninstallExisting exitcode uninstcommand Push `${uninstcommand}` Call UninstallExisting Pop ${exitcode} !macroend Function UninstallExisting Exch $1 ; uninstcommand Push $2 ; Uninstaller Push $3 ; Len StrCpy $3 "" StrCpy $2 $1 1 StrCmp $2 '"' qloop sloop sloop: StrCpy $2 $1 1 $3 IntOp $3 $3 + 1 StrCmp $2 "" +2 StrCmp $2 ' ' 0 sloop IntOp $3 $3 - 1 Goto run qloop: StrCmp $3 "" 0 +2 StrCpy $1 $1 "" 1 ; Remove initial quote IntOp $3 $3 + 1 StrCpy $2 $1 1 $3 StrCmp $2 "" +2 StrCmp $2 '"' 0 qloop run: StrCpy $2 $1 $3 ; Path to uninstaller StrCpy $1 161 ; ERROR_BAD_PATHNAME GetFullPathName $3 "$2\.." ; $InstDir IfFileExists "$2" 0 +4 ExecWait '"$2" /S _?=$3' $1 ; This assumes the existing uninstaller is a NSIS uninstaller, other uninstallers don't support /S nor _?= IntCmp $1 0 "" +2 +2 ; Don't delete the installer if it was aborted Delete "$2" ; Delete the uninstaller RMDir "$3" ; Try to delete $InstDir RMDir "$3\.." ; (Optional) Try to delete the parent of $InstDir Pop $3 Pop $2 Exch $1 ; exitcode FunctionEnd ;-------------------------------------------------------------------------------- ;Variables Var StartMenuFolder ;-------------------------------------------------------------------------------- ;General infos ;Properly display all languages Unicode true ;The name of the installer Name "${PRODUCT_TITLE}" ;The output file path of the installer to be created OutFile "installer\${PRODUCT_INSTALLER}" ;The default installation directory InstallDir "${PRODUCT_DEST}\${PRODUCT_REGPATH}" ;Registry key to check for a install directory from a previous installation InstallDirRegKey ${PRODUCT_REGROOT} "Software\${PRODUCT_REGPATH}" "${PRODUCT_REG_INSTDIR}" ;Request application privileges for admin level privileges RequestExecutionLevel admin ;Show the 'console' in uninstaller ShowUninstDetails "show" ;-------------------------------------------------------------------------------- ;Interface Settings ;Warn the user before aborting the installer !define MUI_ABORTWARNING ;Icon !define MUI_ICON "datas\server-icon.ico" !define MUI_UNICON "datas\server-icon.ico" ;Images !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP "datas\header.bmp" ;150x57 !define MUI_HEADERIMAGE_UNBITMAP "datas\header.bmp" ;150x57 !define MUI_WELCOMEFINISHPAGE_BITMAP "datas\welcomefinish.bmp" ;164x314 !define MUI_UNWELCOMEFINISHPAGE_BITMAP "datas\welcomefinish.bmp" ;164x314 ;Open website if checked !define MUI_FINISHPAGE_SHOWREADME "" !define MUI_FINISHPAGE_SHOWREADME_CHECKED !define MUI_FINISHPAGE_SHOWREADME_TEXT "Ouvir la page web" !define MUI_FINISHPAGE_SHOWREADME_FUNCTION openProductUrl !define MUI_STARTMENUPAGE_NODISABLE !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${PRODUCT_BRAND}\${PRODUCT_NAME}" !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${PRODUCT_BRAND}\${PRODUCT_NAME}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_SMDIR}" ;-------------------------------------------------------------------------------- ;Installer pages ;Welcome page with name and version !insertmacro MUI_PAGE_WELCOME ;Show a page where the user needs to accept a license !insertmacro MUI_PAGE_LICENSE "datas\LICENSE" ;Show a page where the user can customize the components to be installed !insertmacro MUI_PAGE_COMPONENTS ;Show a page where the user can customize the install directory !insertmacro MUI_PAGE_DIRECTORY ;Start Menu Folder Page Configuration !insertmacro MUI_PAGE_STARTMENU ZoggMods $StartMenuFolder ;Show a page where the progress of the install is listed !insertmacro MUI_PAGE_INSTFILES ;Show final finish page !insertmacro MUI_PAGE_FINISH ;-------------------------------------------------------------------------------- ;Uninstaller pages ;Welcome page to uninstaller !insertmacro MUI_UNPAGE_WELCOME ;Show a page where the user needs to confirm the uninstall !insertmacro MUI_UNPAGE_CONFIRM ;Show a page where the progress of the uninstall is listed !insertmacro MUI_UNPAGE_INSTFILES ;Show final finish page !insertmacro MUI_UNPAGE_FINISH ;-------------------------------------------------------------------------------- ;Translations !insertmacro MUI_LANGUAGE "French" ;-------------------------------------------------------------------------------- ;Version Tab (in the )Properties of the file) VIProductVersion "${PRODUCT_VERSION}" VIAddVersionKey "ProductName" "${PRODUCT_TITLE}" VIAddVersionKey "CompanyName" "${PRODUCT_BRAND}" VIAddVersionKey "LegalCopyright" "${PRODUCT_BRAND} ${PRODUCT_YEAR}" VIAddVersionKey "FileDescription" "${PRODUCT_DESCRIPTION}" VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" VIAddVersionKey "LegalTrademarks" "${PRODUCT_BRAND}" ;-------------------------------------------------------------------------------- ;Installer Components ;Main component Section "Composants" SecComposants ;Make this component mandatory so the user is not able to disable it SectionIn RO ;Set output path to the installation directory SetOutPath $INSTDIR ;Copy a file to the current SetOutPath directory File /r "files\*.*" call addRegistryUninstall WriteUninstaller "${PRODUCT_UNINSTALLER}" ; Add Start Menu entries call addStartMenu ;Execute specific shell script call runCommandBatch SectionEnd ;Uninstall component Section "Uninstall" ;Remove files that were installed by the installer and the created uninstaller ;Add 'RMDir /r "$INSTDIR\folder\*.*"' for every folder that was created in the installation directory RMDir /r "$INSTDIR\*.*" ;Remove shortcuts if existing call un.removeStartMenu ;Remove registry keys that were set by the installer call un.removeRegistryUninstall ;Remove directories that were created by the installer RMDir "$INSTDIR" SectionEnd ;-------------------------------------------------------------------------------- ;Descriptions ;Language strings LangString DESC_SecComposants ${LANG_FRENCH} "${PRODUCT_COMPONENTS}" ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecComposants} $(DESC_SecComposants) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------------------------------------------------------- ;Functions ;Add uninstall informations to registry Function addRegistryUninstall ;Write the selected (either default or customized) installation path into the registry WriteRegStr ${PRODUCT_REGROOT} "Software\${PRODUCT_REGPATH}" "${PRODUCT_REG_INSTDIR}" "$INSTDIR" ;Create an uninstaller that will also be recognized by Windows: WriteRegStr ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "DisplayName" "${PRODUCT_TITLE}" WriteRegStr ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "UninstallString" "$\"$INSTDIR\${PRODUCT_UNINSTALLER}$\"" WriteRegStr ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "QuietUninstallString" "$\"$INSTDIR\${PRODUCT_UNINSTALLER}$\" /S" WriteRegDWORD ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "NoModify" 1 WriteRegDWORD ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "NoRepair" 1 WriteRegStr ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "URLInfoAbout" "$\"${PRODUCT_URL}$\"" FunctionEnd ;Add uninstall informations to registry Function un.removeRegistryUninstall ;Remove registry keys that were set by the installer DeleteRegKey ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" ;Remove installation path from registry DeleteRegKey ${PRODUCT_REGROOT} "Software\${PRODUCT_REGPATH}" FunctionEnd ; Add Start Menu entries Function addStartMenu ;Create Start Menu shortcuts !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_TAG} CreateDirectory "$SMPROGRAMS\$StartMenuFolder" CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall ${PRODUCT_TITLE}.lnk" "$INSTDIR\${PRODUCT_UNINSTALLER}" !insertmacro MUI_STARTMENU_WRITE_END FunctionEnd ; Add Start Menu entries Function un.removeStartMenu ;Remove shortcuts if existing !insertmacro MUI_STARTMENU_GETFOLDER ${PRODUCT_TAG} $StartMenuFolder Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall ${PRODUCT_TITLE}.lnk" RMDir "$SMPROGRAMS\$StartMenuFolder" FunctionEnd ;Open product's url Function openProductUrl ExecShell "open" "${PRODUCT_URL}" FunctionEnd ;Run on installer initialization Function .onInit setRebootFlag false ;Show a dialog where the user can select a supported language !insertmacro MUI_LANGDLL_DISPLAY ;Check for previous installed version call checkForPrevious ;Preliminary check for PolyMC installation call checkForPolyMC FunctionEnd ;Execute specific shell script Function runCommandBatch nsExec::ExecToLog /OEM '"$INSTDIR\install.cmd"' Pop $0 FunctionEnd ;Check for PolyMC to be installed Function checkForPolyMC ClearErrors ;Check for registry key marker ReadRegStr $R0 HKCU "${POLYMC_REGKEY}" "${POLYMC_REGVAR}" IfErrors NotFound ;marker not found ;marker found, check for executable IfFileExists "$R0\polymc.exe" Done ;PolyMC not found, offer possibility for force installation anyway NotFound: MessageBox MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_USERICON "PolyMC est requis !$\r$\nVoulez-vous forcer l'installation ?" IDYES true IDNO false true: goto Done false: goto Exit ;In case of problem, open the product's url Exit: ExecShell "open" "${PRODUCT_URL}" Quit Done: FunctionEnd ;Check for previous installed version Function checkForPrevious ReadRegStr $0 ${UNINSTALL_REGROOT} "${UNINSTALL_REGPATH}" "UninstallString" ${If} $0 != "" ${AndIf} ${Cmd} `MessageBox MB_YESNO|MB_ICONQUESTION "Desinstaller la version precedente ?" /SD IDYES IDYES` !insertmacro UninstallExisting $0 $0 ${If} $0 <> 0 MessageBox MB_YESNO|MB_ICONSTOP "Echec de la desinstallation, continuer quand meme ?" /SD IDYES IDYES +2 Abort ${EndIf} ${EndIf} FunctionEnd