NSIS Beyond a Traditional Installation II
Author: Red Wine (talk, contrib) |
Links
- Download the full project here nightdl.zip (51 KB).
Description
Continuing the project to demonstrate how NSIS coding could be useful beyond the traditional creation of an installation, we've created a nice, stand alone, multi language enabled downloader which checks the server for available new release of NSIS nightly builds and requests permission to download it when found.
If it has not found a new release, it asks users if they want to re download the current release.
In this project we're using some functions from the included headers StrFunc and TextFunc and of course the famous Inetc plug-in.
- Applies to NSIS 2.24
NSIS Nightly Builds Downloader
; NSIS Nightly Builds Downloader.nsi ; Requires Inetc plug-in http://nsis.sourceforge.net/Inetc_plug-in ;-------------------------------- ; Script Definitions !define APP_NAME "NSIS Nightly Builds Downloader" !define OUT_DIR "Output" !define TEMP_INI "$PLUGINSDIR\download.ini" !define DOWN_INI "$EXEDIR\download.ini" !define DOWN_LNK "http://nsis.sourceforge.net/nightly/nsis.zip" !define HEAD_GET "$PLUGINSDIR\head.txt" !define FILE_GET "$EXEDIR\nsis-$date2file.zip" !define C_LENGTH "Content-Length" !define LAST_MOD "Last-Modified" !define LANG_STR `"$(InetcStr1)" "$(InetcStr2)" \ "$(InetcStr3)" "$(InetcStr4)" \ "$(InetcStr5)" "$(InetcStr6)" \ "$(InetcStr7)" "$(InetcStr8)"` ;-------------------------------- ; Create Output Directory !system "md ${OUT_DIR}" ;-------------------------------- ; Variables var date2file var header var subheader ;-------------------------------- ; Include Headers !include MUI.nsh !include TextFunc.nsh !insertmacro LineFind !include StrFunc.nsh ${StrStr} ${StrRep} ${StrLoc} ${StrTrimNewLines} # LogicLib is already included in StrFunc header, no need to include it again. ;-------------------------------- ; Script Macros !macro HeaderDisplayText _Txt2Header _Txt2SubHeader StrCpy $header "${_Txt2Header}" StrCpy $subheader "${_Txt2SubHeader}" !macroend !macro InetcDownload _PluginFunc _DownLink _LocalFile Push $0 ClearErrors inetc::${_PluginFunc} /NOPROXY /TRANSLATE ${LANG_STR} "${_DownLink}" "${_LocalFile}" /END Pop $0 # return value = exit code, "OK" if OK ${Unless} $0 == "OK" SetErrors MessageBox MB_ICONEXCLAMATION|MB_OK "$(ErrorMsg) $0" ${EndUnless} Pop $0 !macroend !macro MakeDownloadIni _InputStr _Str2Find _Str2Replace Push $0 Push $1 Push $2 Push $3 ${StrTrimNewLines} $3 "${_InputStr}" ${StrStr} $0 "$3" "${_Str2Find}" ${StrRep} $0 "$0" "${_Str2Find}" "${_Str2Replace}" ${StrLoc} $1 "$0" "=" ">" StrCpy $1 "$0" "$1" ${StrLoc} $2 "$0" "=" "<" Intop $2 $2 - 1 StrCpy $2 "$0" "" "-$2" ${If} $2 != "" WriteINIStr "${TEMP_INI}" "SETTINGS" "$1 " "$2" ${EndIf} Pop $3 Pop $2 Pop $1 Pop $0 !macroend !macro ReplaceIni Delete "${DOWN_INI}" Rename "${TEMP_INI}" "${DOWN_INI}" !macroend !macro CompareIniValues _Value Push $0 Push $1 ClearErrors ReadINIStr $0 "${DOWN_INI}" "SETTINGS" "${_Value}" ReadINIStr $1 "${TEMP_INI}" "SETTINGS" "${_Value}" ${Unless} "$0" == "$1" SetErrors ${EndUnless} Pop $1 Pop $0 !macroend !macro _Date2FileName_ _STRING _RETURN Push $0 Push $1 Push $2 Push $3 StrCpy ${_RETURN} "${_STRING}" ${StrLoc} $0 "${_RETURN}" " " ">" Intop $0 $0 + 1 StrCpy ${_RETURN} "${_RETURN}" "" "$0" ${StrLoc} $0 "${_RETURN}" " " ">" StrCpy $1 "${_RETURN}" "$0" "" Intop $0 $0 + 1 StrCpy ${_RETURN} "${_RETURN}" "" "$0" ${StrLoc} $0 "${_RETURN}" " " ">" StrCpy $2 "${_RETURN}" "$0" "" Intop $0 $0 + 1 StrCpy ${_RETURN} "${_RETURN}" "" "$0" ${StrLoc} $0 "${_RETURN}" " " ">" StrCpy $3 "${_RETURN}" "$0" "" StrCpy ${_RETURN} "$1-$2-$3" Pop $3 Pop $2 Pop $1 Pop $0 !macroend !macro Date2FileName Push $0 ReadINIStr $0 "${TEMP_INI}" "SETTINGS" "${LAST_MOD}" !insertmacro _Date2FileName_ "$0" "$date2file" Pop $0 !macroend !define BuildString "!insertmacro _BUILD_STRINGS" !macro _BUILD_STRINGS _MSG_ _ID_ _STR_ LangString ${_MSG_} "$${LANG_${_ID_}" "${_STR_}" !macroend !macro BUILD_LANGSTRINGS ${BuildString} "ReDowMsg" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_ReDowMsg}" ${BuildString} "FoundMsg" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_FoundMsg}" ${BuildString} "ErrorMsg" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_ErrorMsg}" ${BuildString} "VerHeader" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_VerHeader}" ${BuildString} "NewHeader" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_NewHeader}" ${BuildString} "DlHeader" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_DlHeader}" ${BuildString} "HeaderOk" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_HeaderOk}" ${BuildString} "HeaderEr" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_HeaderEr}" ${BuildString} "VerSubHead" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_VerSubHead}" ${BuildString} "NewSubHead" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_NewSubHead}" ${BuildString} "DlSubHead" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_DlSubHead}" ${BuildString} "SubHeadOk" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_SubHeadOk}" ${BuildString} "SubHeadEr" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_SubHeadEr}" ${BuildString} "DownPrint" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_DownPrint}" ${BuildString} "InetcStr1" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr1}" ${BuildString} "InetcStr2" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr2}" ${BuildString} "InetcStr3" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr3}" ${BuildString} "InetcStr4" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr4}" ${BuildString} "InetcStr5" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr5}" ${BuildString} "InetcStr6" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr6}" ${BuildString} "InetcStr7" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr7}" ${BuildString} "InetcStr8" "${DL_LANGUAGE}" "${${DL_LANGUAGE}_InetcStr8}" !macroend !macro DOWN_LANGUAGE DL_LANGUAGE !insertmacro MUI_LANGUAGE "${DL_LANGUAGE}" !include "DL_${DL_LANGUAGE}.nsh" !insertmacro BUILD_LANGSTRINGS !macroend ;-------------------------------- ; General Attributes Name "${APP_NAME}" Caption "${APP_NAME}" OutFile "${OUT_DIR}\${APP_NAME}.exe" BrandingText "${APP_NAME}" ShowInstDetails nevershow ;-------------------------------- ; MUI Interface & Page Settings !define MUI_PAGE_HEADER_TEXT "$(DlHeader)" !define MUI_PAGE_HEADER_SUBTEXT "$(DlSubHead)" !define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "$header" !define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "$subheader" !insertmacro MUI_PAGE_INSTFILES ;-------------------------------- ; Languages ; Instead of MUI_LANGUAGE use DOWN_LAGUAGE for languages already translated ; see the header dl_english.nsh for details !insertmacro DOWN_LANGUAGE "English" ;!insertmacro DOWN_LANGUAGE "Greek" ;-------------------------------- ; Installer Sections Section "${APP_NAME}" Sec_01 DetailPrint "$(DownPrint)" !insertmacro InetcDownload "head /silent" "${DOWN_LNK}" "${HEAD_GET}" ${Unless} ${Errors} SetDetailsPrint none ${LineFind} "$PLUGINSDIR\head.txt" "" "" LineFindCallBack !insertmacro Date2FileName SetDetailsPrint both ${If} ${FileExists} "${DOWN_INI}" !insertmacro CompareIniValues "${C_LENGTH}" ${AndUnless} ${Errors} !insertmacro CompareIniValues "${LAST_MOD}" ${AndUnless} ${Errors} MessageBox MB_ICONQUESTION|MB_YESNO "$(ReDowMsg)" IDYES _redown !insertmacro HeaderDisplayText "$(VerHeader)" "$(VerSubHead)" Goto _end _redown: Rename "${FILE_GET}" "${FILE_GET}.bak" !insertmacro InetcDownload "get" "${DOWN_LNK}" "${FILE_GET}" ${If} ${Errors} !insertmacro HeaderDisplayText "$(HeaderEr)" "$(SubHeadEr)" ${Else} !insertmacro HeaderDisplayText "$(HeaderOk)" "$(SubHeadOk)" !insertmacro ReplaceIni ${EndIf} _end: ${Else} !insertmacro HeaderDisplayText "$(NewHeader)" "$(NewSubHead)" MessageBox MB_ICONQUESTION|MB_YESNO "$(FoundMsg)" IDNO _exit !insertmacro InetcDownload "get" "${DOWN_LNK}" "${FILE_GET}" ${If} ${Errors} !insertmacro HeaderDisplayText "$(HeaderEr)" "$(SubHeadEr)" ${Else} !insertmacro HeaderDisplayText "$(HeaderOk)" "$(SubHeadOk)" !insertmacro ReplaceIni ${EndIf} _exit: ${EndIf} ${If} ${FileExists} "${FILE_GET}" Delete "${FILE_GET}.bak" ${Else} Rename "${FILE_GET}.bak" "${FILE_GET}" ${EndIf} ${Else} !insertmacro HeaderDisplayText "$(HeaderEr)" "$(SubHeadEr)" ${EndUnless} SectionEnd ;-------------------------------- ; Installer Functions Function LineFindCallBack !insertmacro MakeDownloadIni "$R9" "${C_LENGTH}:" "${C_LENGTH} =" !insertmacro MakeDownloadIni "$R9" "${LAST_MOD}:" "${LAST_MOD} =" Push $0 FunctionEnd
English Translation Header
; dl_english.nsh ; English Language Strings ; Make a copy of this header and save it as dl_[NewLanguage].nsh ; where NewLanguage is the name of a language supported by NSIS e.g. dl_spanish.nsh ; Translate all strings below to the selected language !define ${DL_LANGUAGE}_ReDowMsg "There is not new version on server.$\r$\n\ Do you want to re-download the current version?" !define ${DL_LANGUAGE}_FoundMsg "A new version of the program found on server.$\r$\n\ Do you want to download the new version now?" !define ${DL_LANGUAGE}_ErrorMsg "Download Error:" !define ${DL_LANGUAGE}_VerHeader "New Version Check Out" !define ${DL_LANGUAGE}_NewHeader "Found New Version" !define ${DL_LANGUAGE}_DlHeader "Downloading..." !define ${DL_LANGUAGE}_HeaderOk "Download Complete" !define ${DL_LANGUAGE}_HeaderEr "Download Failed" !define ${DL_LANGUAGE}_VerSubHead "There is not new version on server." !define ${DL_LANGUAGE}_NewSubHead "A new version of the program found on server." !define ${DL_LANGUAGE}_DlSubHead "Please wait while NSIS nightly build is being downloaded." !define ${DL_LANGUAGE}_SubHeadOk "$(^NameDA) was completed successfully." !define ${DL_LANGUAGE}_SubHeadEr "$(^NameDA) was failed." !define ${DL_LANGUAGE}_DownPrint "New version check out (internet connection)" !define ${DL_LANGUAGE}_InetcStr1 "Downloading: %s" !define ${DL_LANGUAGE}_InetcStr2 "Connecting ..." !define ${DL_LANGUAGE}_InetcStr3 "second" !define ${DL_LANGUAGE}_InetcStr4 "minute" !define ${DL_LANGUAGE}_InetcStr5 "hour" !define ${DL_LANGUAGE}_InetcStr6 "s" !define ${DL_LANGUAGE}_InetcStr7 "%d kB (%d%%) of %d kB @ %d.%01d kB/s " !define ${DL_LANGUAGE}_InetcStr8 " (%d %s%s remaining)"
License
This example script is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this script.
Permission is granted to anyone to use this script for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
- The origin of this script must not be misrepresented; you must not claim that you wrote the original code. If you use this script in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- Altered versions must be plainly marked as such, and must not be misrepresented as being the original script.
- This notice may not be removed or altered from any distribution.