nsis.nimf 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. #? stdtmpl(subsChar='?') | standard
  2. #proc generateNsisSetup(c: ConfigData): string =
  3. # result = "; NSIS script generated by niminst\n" &
  4. # "; To regenerate run ``niminst nsis`` or ``koch nsis``\n"
  5. ;--------------------------------
  6. ; Included headers
  7. ; Modern User Interface 2.0 Header
  8. !include "MUI2.nsh"
  9. ; File Functions Header, used to get the current drive root.
  10. !include "FileFunc.nsh"
  11. ;--------------------------------
  12. ; Global variables and defines
  13. !define PRODUCT_NAME "?c.displayName"
  14. !define PRODUCT_VERSION "?c.version"
  15. !define PRODUCT_PUBLISHER "?c.authors"
  16. !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\?{c.name}.exe"
  17. !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
  18. !define PRODUCT_UNINST_ROOT_KEY "HKCU"
  19. !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
  20. ;--------------------------------
  21. ; General Setup Information
  22. ; Name and output file
  23. Name "?{c.name} ?{c.version}"
  24. OutFile "?{c.name}_?{c.version}.exe"
  25. ; Default installation folder
  26. ; This is changed later (in .onInit) to the root directory, if possible.
  27. InstallDir "$PROGRAMFILES?{when sizeof(int) == 8: "64" else: ""}\?{c.name}-?{c.version}\"
  28. ; Get installation folder from registry if available
  29. InstallDirRegKey HKCU "Software\c.name\c.version" ""
  30. ; Request user level application privileges.
  31. RequestExecutionLevel user
  32. ; Allow installation to the root drive directory.
  33. AllowRootDirInstall false
  34. ; Maximum compression!
  35. SetCompressor /SOLID /FINAL lzma
  36. ; Installer and Uninstaller Icons
  37. ; Icon "nim.ico"
  38. ; UninstallIcon "nim.ico"
  39. ; Set installation details to be shown by default
  40. ShowInstDetails show
  41. ShowUnInstDetails show
  42. ;--------------------------------
  43. ; Interface Settings
  44. ; Warn the user if aborting during installation/uninstallation
  45. !define MUI_ABORTWARNING
  46. !define MUI_UNABORTWARNING
  47. ; Don't show a description for sections
  48. !define MUI_COMPONENTSPAGE_NODESC
  49. ;--------------------------------
  50. ; Pages
  51. ; Setup the installer pages
  52. !insertmacro MUI_PAGE_WELCOME
  53. !insertmacro MUI_PAGE_LICENSE "?{expandFilename(c.license)}"
  54. !insertmacro MUI_PAGE_COMPONENTS
  55. !insertmacro MUI_PAGE_DIRECTORY
  56. ; Setup the start menu entry page
  57. var ICONS_GROUP
  58. !define MUI_STARTMENUPAGE_DEFAULTFOLDER "?{c.displayName}"
  59. !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
  60. !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
  61. !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
  62. !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
  63. !insertmacro MUI_PAGE_INSTFILES
  64. !insertmacro MUI_PAGE_FINISH
  65. ; Setup the uninstaller pages
  66. !insertmacro MUI_UNPAGE_CONFIRM
  67. !insertmacro MUI_UNPAGE_INSTFILES
  68. ;--------------------------------
  69. ;Languages
  70. !insertmacro MUI_LANGUAGE "English"
  71. ;--------------------------------
  72. ;Installer Sections
  73. ; The core section. This is comprised of a base Nim installation,
  74. ; such as what would be retrieved via git, and an already bootstrapped
  75. ; Nim binary.
  76. Section "Core Files" CoreSection
  77. ; This is a mandotory section
  78. SectionIn RO
  79. ; Output files to the base installation directory
  80. SetOutPath "$INSTDIR"
  81. ; Only overwrite newer files
  82. SetOverwrite ifnewer
  83. ; Write all the files to the output directory.
  84. #for i in low(FileCategory)..fcWindows:
  85. # for f in items(c.cat[i]):
  86. SetOutPath "$INSTDIR\?{splitFile(f).dir.toWin}"
  87. File "?{expandFilename(f).toWin}"
  88. # end for
  89. #end for
  90. ; Write out the uninstaller
  91. WriteUninstaller "$INSTDIR\uninstaller.exe"
  92. SectionEnd
  93. Section "-Add Registry Keys" RegistrySection
  94. ; Write application registry keys
  95. WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\?{c.name}.exe"
  96. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
  97. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninstaller.exe"
  98. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\?{c.name}.exe"
  99. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
  100. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
  101. ; Reset the output path
  102. SetOutPath "$INSTDIR"
  103. SectionEnd
  104. ; Section for adding the shortcuts related to files and applications
  105. Section "-Setup Shortcuts" ShortcutsSection
  106. !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
  107. CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
  108. #if c.app == appConsole:
  109. CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\start.bat"
  110. CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\start.bat"
  111. #else:
  112. CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe"
  113. CreateShortCut "$DESKTOP\?{c.displayName}.lnk" "$INSTDIR\?{c.name}.exe"
  114. #end if
  115. ; Write the shortcut to the uninstaller
  116. CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninstaller.exe"
  117. !insertmacro MUI_STARTMENU_WRITE_END
  118. SectionEnd
  119. ; Section for adding tools to the PATH variable
  120. Section "Setup Path Environment" PathSection
  121. Push "$INSTDIR\bin"
  122. Call AddToPath
  123. Push "$INSTDIR\dist\mingw"
  124. Call AddToPath
  125. Push "$INSTDIR\dist\mingw\bin"
  126. Call AddToPath
  127. Push "$PROFILE\.nimble\bin"
  128. Call AddToPath
  129. SectionEnd
  130. ; The downloadable sections. These sections are automatically generated by
  131. ; niminst and the template filters.
  132. #var i = 0
  133. #for download in c.downloads:
  134. # inc i
  135. # let d = download.split('|')
  136. # if d.len != 5 and d.len != 6:
  137. # quit("download string needs 5..6 parts: " & download)
  138. # end if
  139. # let sectionName = d[0]
  140. # let dir = d[1]
  141. # let zipName = d[2]
  142. # let size = d[3]
  143. # let url = d[4]
  144. Section /o "?sectionName" ?{i}Section
  145. ; Add the section size to the total size.
  146. AddSize ?size
  147. ; Download the file, and if successful, extract it to the given directory
  148. ; otherwise,
  149. retry:
  150. NSISdl::download "?url" "$TEMP\?zipName"
  151. Pop $0
  152. ${If} $0 == "success"
  153. ZipDLL::extractall "$TEMP\?zipName" "$INSTDIR\?dir"
  154. Delete "$TEMP\?zipName"
  155. ${ElseIf} $0 == "cancel"
  156. MessageBox MB_ICONQUESTION|MB_YESNO|MB_TOPMOST \
  157. "Download of component '?sectionName' cancelled. Continue installation process??" \
  158. IDYES ignore
  159. abort
  160. ${Else}
  161. MessageBox MB_ICONSTOP|MB_ABORTRETRYIGNORE|MB_TOPMOST "Error: $0" \
  162. IDRETRY retry IDIGNORE ignore
  163. abort
  164. ${EndIf}
  165. ; Shortcuts
  166. # if d.len >= 6:
  167. # let startMenuEntry = d[5]
  168. # let e = splitFile(startMenuEntry).name.capitalizeAscii
  169. !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
  170. CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}"
  171. !insertmacro MUI_STARTMENU_WRITE_END
  172. # end if
  173. ignore:
  174. SectionEnd
  175. #end
  176. ;--------------------------------
  177. ; Section Descriptions
  178. ; Series of strings describing each section
  179. ; LangString DESC_CoreSection ${LANG_ENGLISH} "Core Nim files"
  180. ; The macros to actually insert the descriptions into the sections.
  181. ; Each description above should have a corresponding MUI_DESCRIPTION_TEXT
  182. ; macro linking the section to the description.
  183. ; !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  184. ; !insertmacro MUI_DESCRIPTION_TEXT ${CoreSection} $(DESC_CoreSection)
  185. ; !insertmacro MUI_FUNCTION_DESCRIPTION_END
  186. ;--------------------------------
  187. ; Uninstaller Sections
  188. Section "Uninstall"
  189. ; Remove previously created shortcuts
  190. !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP
  191. Delete "$DESKTOP\?{c.displayName}.lnk"
  192. ; Remove installed application files
  193. RMDir /r "$SMPROGRAMS\$ICONS_GROUP"
  194. RMDir /r "$INSTDIR"
  195. ; Remove the previously created registry key
  196. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  197. DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}"
  198. SetAutoClose true
  199. ; Remove entries from the PATH environment variable
  200. Push "$INSTDIR\bin"
  201. Call un.RemoveFromPath
  202. Push "$INSTDIR\dist\mingw"
  203. Call un.RemoveFromPath
  204. Push "$INSTDIR\dist\mingw\bin"
  205. Call un.RemoveFromPath
  206. Push "$PROFILE\.nimble\bin"
  207. Call un.RemoveFromPath
  208. SectionEnd
  209. ;--------------------------------
  210. ; Function hooks
  211. Function .onInit
  212. ${GetRoot} "$EXEDIR" $R0
  213. strCpy $INSTDIR "$R0\?{c.name}"
  214. FunctionEnd
  215. ;--------------------------------------------------------------------
  216. ; Path functions
  217. ;
  218. ; Based on example from:
  219. ; http://nsis.sourceforge.net/Path_Manipulation
  220. ;
  221. ; Actually based on:
  222. ; https://www.smartmontools.org/browser/trunk/smartmontools/os_win32/installer.nsi#L636
  223. !include "WinMessages.nsh"
  224. ; Registry Entry for environment (NT4,2000,XP)
  225. ; All users:
  226. ;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
  227. ; Current user only:
  228. !define Environ 'HKCU "Environment"'
  229. ; AddToPath - Appends dir to PATH
  230. ; (does not work on Win9x/ME)
  231. ;
  232. ; Usage:
  233. ; Push "dir"
  234. ; Call AddToPath
  235. Function AddToPath
  236. Exch $0
  237. Push $1
  238. Push $2
  239. Push $3
  240. Push $4
  241. ; NSIS ReadRegStr returns empty string on string overflow
  242. ; Native calls are used here to check actual length of PATH
  243. ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3)
  244. System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4"
  245. IntCmp $4 0 0 done done
  246. ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
  247. ; RegCloseKey($3)
  248. System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
  249. System::Call "advapi32::RegCloseKey(i $3)"
  250. IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
  251. DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
  252. MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
  253. Goto done
  254. IntCmp $4 0 +5 ; $4 != NO_ERROR
  255. IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
  256. DetailPrint "AddToPath: unexpected error code $4"
  257. Goto done
  258. StrCpy $1 ""
  259. ; Check if already in PATH
  260. Push "$1;"
  261. Push "$0;"
  262. Call StrStr
  263. Pop $2
  264. StrCmp $2 "" 0 done
  265. Push "$1;"
  266. Push "$0\;"
  267. Call StrStr
  268. Pop $2
  269. StrCmp $2 "" 0 done
  270. ; Prevent NSIS string overflow
  271. StrLen $2 $0
  272. StrLen $3 $1
  273. IntOp $2 $2 + $3
  274. IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
  275. IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
  276. DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
  277. MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}."
  278. Goto done
  279. ; Append dir to PATH
  280. DetailPrint "Add to PATH: $0"
  281. StrCpy $2 $1 1 -1
  282. StrCmp $2 ";" 0 +2
  283. StrCpy $1 $1 -1 ; remove trailing ';'
  284. StrCmp $1 "" +2 ; no leading ';'
  285. StrCpy $0 "$1;$0"
  286. WriteRegExpandStr ${Environ} "PATH" $0
  287. SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
  288. done:
  289. Pop $4
  290. Pop $3
  291. Pop $2
  292. Pop $1
  293. Pop $0
  294. FunctionEnd
  295. ; RemoveFromPath - Removes dir from PATH
  296. ;
  297. ; Usage:
  298. ; Push "dir"
  299. ; Call RemoveFromPath
  300. Function un.RemoveFromPath
  301. Exch $0
  302. Push $1
  303. Push $2
  304. Push $3
  305. Push $4
  306. Push $5
  307. Push $6
  308. ReadRegStr $1 ${Environ} "PATH"
  309. StrCpy $5 $1 1 -1
  310. StrCmp $5 ";" +2
  311. StrCpy $1 "$1;" ; ensure trailing ';'
  312. Push $1
  313. Push "$0;"
  314. Call un.StrStr
  315. Pop $2 ; pos of our dir
  316. StrCmp $2 "" done
  317. DetailPrint "Remove from PATH: $0"
  318. StrLen $3 "$0;"
  319. StrLen $4 $2
  320. StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
  321. StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
  322. StrCpy $3 "$5$6"
  323. StrCpy $5 $3 1 -1
  324. StrCmp $5 ";" 0 +2
  325. StrCpy $3 $3 -1 ; remove trailing ';'
  326. WriteRegExpandStr ${Environ} "PATH" $3
  327. SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
  328. done:
  329. Pop $6
  330. Pop $5
  331. Pop $4
  332. Pop $3
  333. Pop $2
  334. Pop $1
  335. Pop $0
  336. FunctionEnd
  337. ; StrStr - find substring in a string
  338. ;
  339. ; Usage:
  340. ; Push "this is some string"
  341. ; Push "some"
  342. ; Call StrStr
  343. ; Pop $0 ; "some string"
  344. !macro StrStr un
  345. Function ${un}StrStr
  346. Exch $R1 ; $R1=substring, stack=[old$R1,string,...]
  347. Exch ; stack=[string,old$R1,...]
  348. Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...]
  349. Push $R3
  350. Push $R4
  351. Push $R5
  352. StrLen $R3 $R1
  353. StrCpy $R4 0
  354. ; $R1=substring, $R2=string, $R3=strlen(substring)
  355. ; $R4=count, $R5=tmp
  356. loop:
  357. StrCpy $R5 $R2 $R3 $R4
  358. StrCmp $R5 $R1 done
  359. StrCmp $R5 "" done
  360. IntOp $R4 $R4 + 1
  361. Goto loop
  362. done:
  363. StrCpy $R1 $R2 "" $R4
  364. Pop $R5
  365. Pop $R4
  366. Pop $R3
  367. Pop $R2
  368. Exch $R1 ; $R1=old$R1, stack=[result,...]
  369. FunctionEnd
  370. !macroend
  371. !insertmacro StrStr ""
  372. !insertmacro StrStr "un."