123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- #? stdtmpl(subsChar='?') | standard
- #proc generateNsisSetup(c: ConfigData): string =
- # result = "; NSIS script generated by niminst\n" &
- # "; To regenerate run ``niminst nsis`` or ``koch nsis``\n"
- ;--------------------------------
- ; Included headers
- ; Modern User Interface 2.0 Header
- !include "MUI2.nsh"
- ; File Functions Header, used to get the current drive root.
- !include "FileFunc.nsh"
- ;--------------------------------
- ; Global variables and defines
- !define PRODUCT_NAME "?c.displayName"
- !define PRODUCT_VERSION "?c.version"
- !define PRODUCT_PUBLISHER "?c.authors"
- !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\?{c.name}.exe"
- !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
- !define PRODUCT_UNINST_ROOT_KEY "HKCU"
- !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
- ;--------------------------------
- ; General Setup Information
- ; Name and output file
- Name "?{c.name} ?{c.version}"
- OutFile "?{c.name}_?{c.version}.exe"
- ; Default installation folder
- ; This is changed later (in .onInit) to the root directory, if possible.
- InstallDir "$PROGRAMFILES?{when sizeof(int) == 8: "64" else: ""}\?{c.name}-?{c.version}\"
- ; Get installation folder from registry if available
- InstallDirRegKey HKCU "Software\c.name\c.version" ""
- ; Request user level application privileges.
- RequestExecutionLevel user
- ; Allow installation to the root drive directory.
- AllowRootDirInstall false
- ; Maximum compression!
- SetCompressor /SOLID /FINAL lzma
- ; Installer and Uninstaller Icons
- ; Icon "nim.ico"
- ; UninstallIcon "nim.ico"
- ; Set installation details to be shown by default
- ShowInstDetails show
- ShowUnInstDetails show
- ;--------------------------------
- ; Interface Settings
- ; Warn the user if aborting during installation/uninstallation
- !define MUI_ABORTWARNING
- !define MUI_UNABORTWARNING
- ; Don't show a description for sections
- !define MUI_COMPONENTSPAGE_NODESC
- ;--------------------------------
- ; Pages
- ; Setup the installer pages
- !insertmacro MUI_PAGE_WELCOME
- !insertmacro MUI_PAGE_LICENSE "?{expandFilename(c.license)}"
- !insertmacro MUI_PAGE_COMPONENTS
- !insertmacro MUI_PAGE_DIRECTORY
- ; Setup the start menu entry page
- var ICONS_GROUP
- !define MUI_STARTMENUPAGE_DEFAULTFOLDER "?{c.displayName}"
- !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
- !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
- !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
- !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
- !insertmacro MUI_PAGE_INSTFILES
- !insertmacro MUI_PAGE_FINISH
- ; Setup the uninstaller pages
- !insertmacro MUI_UNPAGE_CONFIRM
- !insertmacro MUI_UNPAGE_INSTFILES
- ;--------------------------------
- ;Languages
- !insertmacro MUI_LANGUAGE "English"
- ;--------------------------------
- ;Installer Sections
- ; The core section. This is comprised of a base Nim installation,
- ; such as what would be retrieved via git, and an already bootstrapped
- ; Nim binary.
- Section "Core Files" CoreSection
- ; This is a mandotory section
- SectionIn RO
- ; Output files to the base installation directory
- SetOutPath "$INSTDIR"
- ; Only overwrite newer files
- SetOverwrite ifnewer
- ; Write all the files to the output directory.
- #for i in low(FileCategory)..fcWindows:
- # for f in items(c.cat[i]):
- SetOutPath "$INSTDIR\?{splitFile(f).dir.toWin}"
- File "?{expandFilename(f).toWin}"
- # end for
- #end for
- ; Write out the uninstaller
- WriteUninstaller "$INSTDIR\uninstaller.exe"
- SectionEnd
- Section "-Add Registry Keys" RegistrySection
- ; Write application registry keys
- WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\?{c.name}.exe"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninstaller.exe"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\?{c.name}.exe"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
- ; Reset the output path
- SetOutPath "$INSTDIR"
- SectionEnd
- ; Section for adding the shortcuts related to files and applications
- Section "-Setup Shortcuts" ShortcutsSection
- !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
- CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
- #if c.app == appConsole:
- CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\start.bat"
- CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\start.bat"
- #else:
- CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe"
- CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe"
- #end if
- ; Write the shortcut to the uninstaller
- CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninstaller.exe"
- !insertmacro MUI_STARTMENU_WRITE_END
- SectionEnd
- ; Section for adding tools to the PATH variable
- Section "Setup Path Environment" PathSection
- Push "$INSTDIR\bin"
- Call AddToPath
- Push "$INSTDIR\dist\mingw"
- Call AddToPath
- Push "$INSTDIR\dist\mingw\bin"
- Call AddToPath
- Push "$PROFILE\.nimble\bin"
- Call AddToPath
- SectionEnd
- ; The downloadable sections. These sections are automatically generated by
- ; niminst and the template filters.
- #var i = 0
- #for download in c.downloads:
- # inc i
- # let d = download.split('|')
- # if d.len != 5 and d.len != 6:
- # quit("download string needs 5..6 parts: " & download)
- # end if
- # let sectionName = d[0]
- # let dir = d[1]
- # let zipName = d[2]
- # let size = d[3]
- # let url = d[4]
- Section /o "?sectionName" ?{i}Section
- ; Add the section size to the total size.
- AddSize ?size
- ; Download the file, and if successful, extract it to the given directory
- ; otherwise,
- retry:
- NSISdl::download "?url" "$TEMP\?zipName"
- Pop $0
- ${If} $0 == "success"
- ZipDLL::extractall "$TEMP\?zipName" "$INSTDIR\?dir"
- Delete "$TEMP\?zipName"
- ${ElseIf} $0 == "cancel"
- MessageBox MB_ICONQUESTION|MB_YESNO|MB_TOPMOST \
- "Download of component '?sectionName' cancelled. Continue installation process??" \
- IDYES ignore
- abort
- ${Else}
- MessageBox MB_ICONSTOP|MB_ABORTRETRYIGNORE|MB_TOPMOST "Error: $0" \
- IDRETRY retry IDIGNORE ignore
- abort
- ${EndIf}
- ; Shortcuts
- # if d.len >= 6:
- # let startMenuEntry = d[5]
- # let e = splitFile(startMenuEntry).name.capitalizeAscii
- !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
- CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}"
- !insertmacro MUI_STARTMENU_WRITE_END
- # end if
- ignore:
- SectionEnd
- #end
- ;--------------------------------
- ; Section Descriptions
- ; Series of strings describing each section
- ; LangString DESC_CoreSection ${LANG_ENGLISH} "Core Nim files"
- ; The macros to actually insert the descriptions into the sections.
- ; Each description above should have a corresponding MUI_DESCRIPTION_TEXT
- ; macro linking the section to the description.
- ; !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
- ; !insertmacro MUI_DESCRIPTION_TEXT ${CoreSection} $(DESC_CoreSection)
- ; !insertmacro MUI_FUNCTION_DESCRIPTION_END
- ;--------------------------------
- ; Uninstaller Sections
- Section "Uninstall"
- ; Remove previously created shortcuts
- !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP
- Delete "$DESKTOP\?{c.displayName}.lnk"
- ; Remove installed application files
- RMDir /r "$SMPROGRAMS\$ICONS_GROUP"
- RMDir /r "$INSTDIR"
- ; Remove the previously created registry key
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
- DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}"
- SetAutoClose true
- ; Remove entries from the PATH environment variable
- Push "$INSTDIR\bin"
- Call un.RemoveFromPath
- Push "$INSTDIR\dist\mingw"
- Call un.RemoveFromPath
- Push "$INSTDIR\dist\mingw\bin"
- Call un.RemoveFromPath
- Push "$PROFILE\.nimble\bin"
- Call un.RemoveFromPath
- SectionEnd
- ;--------------------------------
- ; Function hooks
- Function .onInit
- ${GetRoot} "$EXEDIR" $R0
- strCpy $INSTDIR "$R0\?{c.name}"
- FunctionEnd
- ;--------------------------------------------------------------------
- ; Path functions
- ;
- ; Based on example from:
- ; http://nsis.sourceforge.net/Path_Manipulation
- ;
- ; Actually based on:
- ; https://www.smartmontools.org/browser/trunk/smartmontools/os_win32/installer.nsi#L636
- !include "WinMessages.nsh"
- ; Registry Entry for environment (NT4,2000,XP)
- ; All users:
- ;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
- ; Current user only:
- !define Environ 'HKCU "Environment"'
- ; AddToPath - Appends dir to PATH
- ; (does not work on Win9x/ME)
- ;
- ; Usage:
- ; Push "dir"
- ; Call AddToPath
- Function AddToPath
- Exch $0
- Push $1
- Push $2
- Push $3
- Push $4
- ; NSIS ReadRegStr returns empty string on string overflow
- ; Native calls are used here to check actual length of PATH
- ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3)
- System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4"
- IntCmp $4 0 0 done done
- ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
- ; RegCloseKey($3)
- System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
- System::Call "advapi32::RegCloseKey(i $3)"
- IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
- DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
- MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
- Goto done
- IntCmp $4 0 +5 ; $4 != NO_ERROR
- IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
- DetailPrint "AddToPath: unexpected error code $4"
- Goto done
- StrCpy $1 ""
- ; Check if already in PATH
- Push "$1;"
- Push "$0;"
- Call StrStr
- Pop $2
- StrCmp $2 "" 0 done
- Push "$1;"
- Push "$0\;"
- Call StrStr
- Pop $2
- StrCmp $2 "" 0 done
- ; Prevent NSIS string overflow
- StrLen $2 $0
- StrLen $3 $1
- IntOp $2 $2 + $3
- IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
- IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
- DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
- MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}."
- Goto done
- ; Append dir to PATH
- DetailPrint "Add to PATH: $0"
- StrCpy $2 $1 1 -1
- StrCmp $2 ";" 0 +2
- StrCpy $1 $1 -1 ; remove trailing ';'
- StrCmp $1 "" +2 ; no leading ';'
- StrCpy $0 "$1;$0"
- WriteRegExpandStr ${Environ} "PATH" $0
- SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
- done:
- Pop $4
- Pop $3
- Pop $2
- Pop $1
- Pop $0
- FunctionEnd
- ; RemoveFromPath - Removes dir from PATH
- ;
- ; Usage:
- ; Push "dir"
- ; Call RemoveFromPath
- Function un.RemoveFromPath
- Exch $0
- Push $1
- Push $2
- Push $3
- Push $4
- Push $5
- Push $6
- ReadRegStr $1 ${Environ} "PATH"
- StrCpy $5 $1 1 -1
- StrCmp $5 ";" +2
- StrCpy $1 "$1;" ; ensure trailing ';'
- Push $1
- Push "$0;"
- Call un.StrStr
- Pop $2 ; pos of our dir
- StrCmp $2 "" done
- DetailPrint "Remove from PATH: $0"
- StrLen $3 "$0;"
- StrLen $4 $2
- StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
- StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
- StrCpy $3 "$5$6"
- StrCpy $5 $3 1 -1
- StrCmp $5 ";" 0 +2
- StrCpy $3 $3 -1 ; remove trailing ';'
- WriteRegExpandStr ${Environ} "PATH" $3
- SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
- done:
- Pop $6
- Pop $5
- Pop $4
- Pop $3
- Pop $2
- Pop $1
- Pop $0
- FunctionEnd
- ; StrStr - find substring in a string
- ;
- ; Usage:
- ; Push "this is some string"
- ; Push "some"
- ; Call StrStr
- ; Pop $0 ; "some string"
- !macro StrStr un
- Function ${un}StrStr
- Exch $R1 ; $R1=substring, stack=[old$R1,string,...]
- Exch ; stack=[string,old$R1,...]
- Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...]
- Push $R3
- Push $R4
- Push $R5
- StrLen $R3 $R1
- StrCpy $R4 0
- ; $R1=substring, $R2=string, $R3=strlen(substring)
- ; $R4=count, $R5=tmp
- loop:
- StrCpy $R5 $R2 $R3 $R4
- StrCmp $R5 $R1 done
- StrCmp $R5 "" done
- IntOp $R4 $R4 + 1
- Goto loop
- done:
- StrCpy $R1 $R2 "" $R4
- Pop $R5
- Pop $R4
- Pop $R3
- Pop $R2
- Exch $R1 ; $R1=old$R1, stack=[result,...]
- FunctionEnd
- !macroend
- !insertmacro StrStr ""
- !insertmacro StrStr "un."
|