installer.nsi 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. ; This file is copied from https://github.com/tauri-apps/tauri/blob/tauri-v1.5/tooling/bundler/src/bundle/windows/templates/installer.nsi
  2. ; and edit to fit the needs of the project. the latest tauri 2.x has a different base nsi script.
  3. Unicode true
  4. ; Set the compression algorithm. Default is LZMA.
  5. !if "{{compression}}" == ""
  6. SetCompressor /SOLID lzma
  7. !else
  8. SetCompressor /SOLID "{{compression}}"
  9. !endif
  10. !include MUI2.nsh
  11. !include FileFunc.nsh
  12. !include x64.nsh
  13. !include WordFunc.nsh
  14. !include "LogicLib.nsh"
  15. !include "StrFunc.nsh"
  16. ${StrCase}
  17. ${StrLoc}
  18. !define MANUFACTURER "{{manufacturer}}"
  19. !define PRODUCTNAME "{{product_name}}"
  20. !define VERSION "{{version}}"
  21. !define VERSIONWITHBUILD "{{version_with_build}}"
  22. !define SHORTDESCRIPTION "{{short_description}}"
  23. !define INSTALLMODE "{{install_mode}}"
  24. !define LICENSE "{{license}}"
  25. !define INSTALLERICON "{{installer_icon}}"
  26. !define SIDEBARIMAGE "{{sidebar_image}}"
  27. !define HEADERIMAGE "{{header_image}}"
  28. !define MAINBINARYNAME "{{main_binary_name}}"
  29. !define MAINBINARYSRCPATH "{{main_binary_path}}"
  30. !define BUNDLEID "{{bundle_id}}"
  31. !define COPYRIGHT "{{copyright}}"
  32. !define OUTFILE "{{out_file}}"
  33. !define ARCH "{{arch}}"
  34. !define PLUGINSPATH "{{additional_plugins_path}}"
  35. !define ALLOWDOWNGRADES "{{allow_downgrades}}"
  36. !define DISPLAYLANGUAGESELECTOR "{{display_language_selector}}"
  37. !define INSTALLWEBVIEW2MODE "{{install_webview2_mode}}"
  38. !define WEBVIEW2INSTALLERARGS "{{webview2_installer_args}}"
  39. !define WEBVIEW2BOOTSTRAPPERPATH "{{webview2_bootstrapper_path}}"
  40. !define WEBVIEW2INSTALLERPATH "{{webview2_installer_path}}"
  41. !define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}"
  42. !define MANUPRODUCTKEY "Software\${MANUFACTURER}\${PRODUCTNAME}"
  43. !define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}"
  44. !define ESTIMATEDSIZE "{{estimated_size}}"
  45. Name "${PRODUCTNAME}"
  46. BrandingText "${COPYRIGHT}"
  47. OutFile "${OUTFILE}"
  48. VIProductVersion "${VERSIONWITHBUILD}"
  49. VIAddVersionKey "ProductName" "${PRODUCTNAME}"
  50. VIAddVersionKey "FileDescription" "${SHORTDESCRIPTION}"
  51. VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
  52. VIAddVersionKey "FileVersion" "${VERSION}"
  53. VIAddVersionKey "ProductVersion" "${VERSION}"
  54. ; Plugins path, currently exists for linux only
  55. !if "${PLUGINSPATH}" != ""
  56. !addplugindir "${PLUGINSPATH}"
  57. !endif
  58. !if "${UNINSTALLERSIGNCOMMAND}" != ""
  59. !uninstfinalize '${UNINSTALLERSIGNCOMMAND}'
  60. !endif
  61. ; Handle install mode, `perUser`, `perMachine` or `both`
  62. !if "${INSTALLMODE}" == "perMachine"
  63. RequestExecutionLevel highest
  64. !endif
  65. !if "${INSTALLMODE}" == "currentUser"
  66. RequestExecutionLevel user
  67. !endif
  68. !if "${INSTALLMODE}" == "both"
  69. !define MULTIUSER_MUI
  70. !define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCTNAME}"
  71. !define MULTIUSER_INSTALLMODE_COMMANDLINE
  72. !if "${ARCH}" == "x64"
  73. !define MULTIUSER_USE_PROGRAMFILES64
  74. !else if "${ARCH}" == "arm64"
  75. !define MULTIUSER_USE_PROGRAMFILES64
  76. !endif
  77. !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}"
  78. !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser"
  79. !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME
  80. !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation
  81. !define MULTIUSER_EXECUTIONLEVEL Highest
  82. !include MultiUser.nsh
  83. !endif
  84. ; installer icon
  85. !if "${INSTALLERICON}" != ""
  86. !define MUI_ICON "${INSTALLERICON}"
  87. !endif
  88. ; installer sidebar image
  89. !if "${SIDEBARIMAGE}" != ""
  90. !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}"
  91. !endif
  92. ; installer header image
  93. !if "${HEADERIMAGE}" != ""
  94. !define MUI_HEADERIMAGE
  95. !define MUI_HEADERIMAGE_BITMAP "${HEADERIMAGE}"
  96. !endif
  97. ; Define registry key to store installer language
  98. !define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
  99. !define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}"
  100. !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
  101. ; Installer pages, must be ordered as they appear
  102. ; 1. Welcome Page
  103. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  104. !insertmacro MUI_PAGE_WELCOME
  105. ; 2. License Page (if defined)
  106. !if "${LICENSE}" != ""
  107. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  108. !insertmacro MUI_PAGE_LICENSE "${LICENSE}"
  109. !endif
  110. ; 3. Install mode (if it is set to `both`)
  111. !if "${INSTALLMODE}" == "both"
  112. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  113. !insertmacro MULTIUSER_PAGE_INSTALLMODE
  114. !endif
  115. ; 4. Custom page to ask user if he wants to reinstall/uninstall
  116. ; only if a previous installtion was detected
  117. Var ReinstallPageCheck
  118. Page custom PageReinstall PageLeaveReinstall
  119. Function PageReinstall
  120. ; Uninstall previous WiX installation if exists.
  121. ;
  122. ; A WiX installer stores the isntallation info in registry
  123. ; using a UUID and so we have to loop through all keys under
  124. ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`
  125. ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER}
  126. ;
  127. ; This has a potentional issue that there maybe another installation that matches
  128. ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer,
  129. ; however, this should be fine since the user will have to confirm the uninstallation
  130. ; and they can chose to abort it if doesn't make sense.
  131. StrCpy $0 0
  132. wix_loop:
  133. EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0
  134. StrCmp $1 "" wix_done ; Exit loop if there is no more keys to loop on
  135. IntOp $0 $0 + 1
  136. ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName"
  137. ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher"
  138. StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop
  139. ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString"
  140. ${StrCase} $R1 $R0 "L"
  141. ${StrLoc} $R0 $R1 "msiexec" ">"
  142. StrCmp $R0 0 0 wix_done
  143. StrCpy $R7 "wix"
  144. StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1"
  145. Goto compare_version
  146. wix_done:
  147. ; Check if there is an existing installation, if not, abort the reinstall page
  148. ReadRegStr $R0 SHCTX "${UNINSTKEY}" ""
  149. ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString"
  150. ${IfThen} "$R0$R1" == "" ${|} Abort ${|}
  151. ; Compare this installar version with the existing installation
  152. ; and modify the messages presented to the user accordingly
  153. compare_version:
  154. StrCpy $R4 "$(older)"
  155. ${If} $R7 == "wix"
  156. ReadRegStr $R0 HKLM "$R6" "DisplayVersion"
  157. ${Else}
  158. ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion"
  159. ${EndIf}
  160. ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|}
  161. nsis_tauri_utils::SemverCompare "${VERSION}" $R0
  162. Pop $R0
  163. ; Reinstalling the same version
  164. ${If} $R0 == 0
  165. StrCpy $R1 "$(alreadyInstalledLong)"
  166. StrCpy $R2 "$(addOrReinstall)"
  167. StrCpy $R3 "$(uninstallApp)"
  168. !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)"
  169. StrCpy $R5 "2"
  170. ; Upgrading
  171. ${ElseIf} $R0 == 1
  172. StrCpy $R1 "$(olderOrUnknownVersionInstalled)"
  173. StrCpy $R2 "$(uninstallBeforeInstalling)"
  174. StrCpy $R3 "$(dontUninstall)"
  175. !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)"
  176. StrCpy $R5 "1"
  177. ; Downgrading
  178. ${ElseIf} $R0 == -1
  179. StrCpy $R1 "$(newerVersionInstalled)"
  180. StrCpy $R2 "$(uninstallBeforeInstalling)"
  181. !if "${ALLOWDOWNGRADES}" == "true"
  182. StrCpy $R3 "$(dontUninstall)"
  183. !else
  184. StrCpy $R3 "$(dontUninstallDowngrade)"
  185. !endif
  186. !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)"
  187. StrCpy $R5 "1"
  188. ${Else}
  189. Abort
  190. ${EndIf}
  191. Call SkipIfPassive
  192. nsDialogs::Create 1018
  193. Pop $R4
  194. ${IfThen} $(^RTL) == 1 ${|} nsDialogs::SetRTL $(^RTL) ${|}
  195. ${NSD_CreateLabel} 0 0 100% 24u $R1
  196. Pop $R1
  197. ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2
  198. Pop $R2
  199. ${NSD_OnClick} $R2 PageReinstallUpdateSelection
  200. ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3
  201. Pop $R3
  202. ; disable this radio button if downgrading and downgrades are disabled
  203. !if "${ALLOWDOWNGRADES}" == "false"
  204. ${IfThen} $R0 == -1 ${|} EnableWindow $R3 0 ${|}
  205. !endif
  206. ${NSD_OnClick} $R3 PageReinstallUpdateSelection
  207. ; Check the first radio button if this the first time
  208. ; we enter this page or if the second button wasn't
  209. ; selected the last time we were on this page
  210. ${If} $ReinstallPageCheck != 2
  211. SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0
  212. ${Else}
  213. SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0
  214. ${EndIf}
  215. ${NSD_SetFocus} $R2
  216. nsDialogs::Show
  217. FunctionEnd
  218. Function PageReinstallUpdateSelection
  219. ${NSD_GetState} $R2 $R1
  220. ${If} $R1 == ${BST_CHECKED}
  221. StrCpy $ReinstallPageCheck 1
  222. ${Else}
  223. StrCpy $ReinstallPageCheck 2
  224. ${EndIf}
  225. FunctionEnd
  226. Function PageLeaveReinstall
  227. ${NSD_GetState} $R2 $R1
  228. ; $R5 holds whether we are reinstalling the same version or not
  229. ; $R5 == "1" -> different versions
  230. ; $R5 == "2" -> same version
  231. ;
  232. ; $R1 holds the radio buttons state. its meaning is dependant on the context
  233. StrCmp $R5 "1" 0 +2 ; Existing install is not the same version?
  234. StrCmp $R1 "1" reinst_uninstall reinst_done ; $R1 == "1", then user chose to uninstall existing version, otherwise skip uninstalling
  235. StrCmp $R1 "1" reinst_done ; Same version? skip uninstalling
  236. reinst_uninstall:
  237. HideWindow
  238. ClearErrors
  239. ${If} $R7 == "wix"
  240. ReadRegStr $R1 HKLM "$R6" "UninstallString"
  241. ExecWait '$R1' $0
  242. ${Else}
  243. ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" ""
  244. ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString"
  245. ExecWait '$R1 /P _?=$4' $0
  246. ${EndIf}
  247. BringToFront
  248. ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code
  249. ${If} $0 <> 0
  250. ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe"
  251. ${If} $0 = 1 ; User aborted uninstaller?
  252. StrCmp $R5 "2" 0 +2 ; Is the existing install the same version?
  253. Quit ; ...yes, already installed, we are done
  254. Abort
  255. ${EndIf}
  256. MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)"
  257. Abort
  258. ${Else}
  259. StrCpy $0 $R1 1
  260. ${IfThen} $0 == '"' ${|} StrCpy $R1 $R1 -1 1 ${|} ; Strip quotes from UninstallString
  261. Delete $R1
  262. RMDir $INSTDIR
  263. ${EndIf}
  264. reinst_done:
  265. FunctionEnd
  266. ; 5. Choose install directoy page
  267. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  268. !insertmacro MUI_PAGE_DIRECTORY
  269. ; 6. Start menu shortcut page
  270. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  271. Var AppStartMenuFolder
  272. !insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder
  273. ; 7. Installation page
  274. !insertmacro MUI_PAGE_INSTFILES
  275. ; 8. Finish page
  276. ;
  277. ; Don't auto jump to finish page after installation page,
  278. ; because the installation page has useful info that can be used debug any issues with the installer.
  279. !define MUI_FINISHPAGE_NOAUTOCLOSE
  280. ; Use show readme button in the finish page as a button create a desktop shortcut
  281. !define MUI_FINISHPAGE_SHOWREADME
  282. !define MUI_FINISHPAGE_SHOWREADME_TEXT "$(createDesktop)"
  283. !define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDesktopShortcut
  284. ; Show run app after installation.
  285. !define MUI_FINISHPAGE_RUN "$INSTDIR\${MAINBINARYNAME}.exe"
  286. !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  287. !insertmacro MUI_PAGE_FINISH
  288. ; Uninstaller Pages
  289. ; 1. Confirm uninstall page
  290. Var DeleteAppDataCheckbox
  291. Var DeleteAppDataCheckboxState
  292. !define /ifndef WS_EX_LAYOUTRTL 0x00400000
  293. !define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow
  294. Function un.ConfirmShow
  295. FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog
  296. ${If} $(^RTL) == 1
  297. System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE}|${WS_EX_LAYOUTRTL},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 50,i 100,i 400, i 25,i$1,i0,i0,i0)i.s'
  298. ${Else}
  299. System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 0,i 100,i 400, i 25,i$1,i0,i0,i0)i.s'
  300. ${EndIf}
  301. Pop $DeleteAppDataCheckbox
  302. SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1
  303. SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1
  304. FunctionEnd
  305. !define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave
  306. Function un.ConfirmLeave
  307. SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState
  308. FunctionEnd
  309. !insertmacro MUI_UNPAGE_CONFIRM
  310. ; 2. Uninstalling Page
  311. !insertmacro MUI_UNPAGE_INSTFILES
  312. ;Languages
  313. {{#each languages}}
  314. !insertmacro MUI_LANGUAGE "{{this}}"
  315. {{/each}}
  316. !insertmacro MUI_RESERVEFILE_LANGDLL
  317. {{#each language_files}}
  318. !include "{{this}}"
  319. {{/each}}
  320. !macro SetContext
  321. !if "${INSTALLMODE}" == "currentUser"
  322. SetShellVarContext current
  323. !else if "${INSTALLMODE}" == "perMachine"
  324. SetShellVarContext all
  325. !endif
  326. ${If} ${RunningX64}
  327. !if "${ARCH}" == "x64"
  328. SetRegView 64
  329. !else if "${ARCH}" == "arm64"
  330. SetRegView 64
  331. !else
  332. SetRegView 32
  333. !endif
  334. ${EndIf}
  335. !macroend
  336. Var PassiveMode
  337. Function .onInit
  338. ${GetOptions} $CMDLINE "/P" $PassiveMode
  339. IfErrors +2 0
  340. StrCpy $PassiveMode 1
  341. !if "${DISPLAYLANGUAGESELECTOR}" == "true"
  342. !insertmacro MUI_LANGDLL_DISPLAY
  343. !endif
  344. !insertmacro SetContext
  345. ${If} $INSTDIR == ""
  346. ; Set default install location
  347. !if "${INSTALLMODE}" == "perMachine"
  348. ${If} ${RunningX64}
  349. !if "${ARCH}" == "x64"
  350. StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}"
  351. !else if "${ARCH}" == "arm64"
  352. StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}"
  353. !else
  354. StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}"
  355. !endif
  356. ${Else}
  357. StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}"
  358. ${EndIf}
  359. !else if "${INSTALLMODE}" == "currentUser"
  360. StrCpy $INSTDIR "$LOCALAPPDATA\${PRODUCTNAME}"
  361. !endif
  362. Call RestorePreviousInstallLocation
  363. ${EndIf}
  364. !if "${INSTALLMODE}" == "both"
  365. !insertmacro MULTIUSER_INIT
  366. !endif
  367. FunctionEnd
  368. !macro CheckAllVergeProcesses
  369. ; Check if Clash Verge.exe is running
  370. nsis_tauri_utils::FindProcess "Clash Verge.exe"
  371. ${If} $R0 != 0
  372. ; Kill the process
  373. !if "${INSTALLMODE}" == "currentUser"
  374. nsis_tauri_utils::KillProcessCurrentUser "Clash Verge.exe"
  375. !else
  376. nsis_tauri_utils::KillProcess "Clash Verge.exe"
  377. !endif
  378. ${EndIf}
  379. ; Check if clash-verge-service.exe is running
  380. nsis_tauri_utils::FindProcess "clash-verge-service.exe"
  381. ${If} $R0 != 0
  382. ; Kill the process
  383. !if "${INSTALLMODE}" == "currentUser"
  384. nsis_tauri_utils::KillProcessCurrentUser "clash-verge-service.exe"
  385. !else
  386. nsis_tauri_utils::KillProcess "clash-verge-service.exe"
  387. !endif
  388. ${EndIf}
  389. ; Check if clash-meta-alpha.exe is running
  390. nsis_tauri_utils::FindProcess "clash-meta-alpha.exe"
  391. ${If} $R0 != 0
  392. ; Kill the process
  393. !if "${INSTALLMODE}" == "currentUser"
  394. nsis_tauri_utils::KillProcessCurrentUser "clash-meta-alpha.exe"
  395. !else
  396. nsis_tauri_utils::KillProcess "clash-meta-alpha.exe"
  397. !endif
  398. ${EndIf}
  399. ; Check if clash-meta.exe is running
  400. nsis_tauri_utils::FindProcess "clash-meta.exe"
  401. ${If} $R0 != 0
  402. ; Kill the process
  403. !if "${INSTALLMODE}" == "currentUser"
  404. nsis_tauri_utils::KillProcessCurrentUser "clash-meta.exe"
  405. !else
  406. nsis_tauri_utils::KillProcess "clash-meta.exe"
  407. !endif
  408. ${EndIf}
  409. !macroend
  410. Section
  411. !insertmacro CheckAllVergeProcesses
  412. SectionEnd
  413. Section EarlyChecks
  414. ; Abort silent installer if downgrades is disabled
  415. !if "${ALLOWDOWNGRADES}" == "false"
  416. IfSilent 0 silent_downgrades_done
  417. ; If downgrading
  418. ${If} $R0 == -1
  419. System::Call 'kernel32::AttachConsole(i -1)i.r0'
  420. ${If} $0 != 0
  421. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  422. System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color
  423. FileWrite $0 "$(silentDowngrades)"
  424. ${EndIf}
  425. Abort
  426. ${EndIf}
  427. silent_downgrades_done:
  428. !endif
  429. SectionEnd
  430. Section WebView2
  431. ; Check if Webview2 is already installed and skip this section
  432. ${If} ${RunningX64}
  433. ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
  434. ${Else}
  435. ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
  436. ${EndIf}
  437. ReadRegStr $5 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
  438. StrCmp $4 "" 0 webview2_done
  439. StrCmp $5 "" 0 webview2_done
  440. ; Webview2 install modes
  441. !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper"
  442. Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe"
  443. DetailPrint "$(webview2Downloading)"
  444. nsis_tauri_utils::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe"
  445. Pop $0
  446. ${If} $0 == 0
  447. DetailPrint "$(webview2DownloadSuccess)"
  448. ${Else}
  449. DetailPrint "$(webview2DownloadError)"
  450. Abort "$(webview2AbortError)"
  451. ${EndIf}
  452. StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe"
  453. Goto install_webview2
  454. !endif
  455. !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper"
  456. Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe"
  457. File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}"
  458. DetailPrint "$(installingWebview2)"
  459. StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe"
  460. Goto install_webview2
  461. !endif
  462. !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller"
  463. Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe"
  464. File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}"
  465. DetailPrint "$(installingWebview2)"
  466. StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe"
  467. Goto install_webview2
  468. !endif
  469. Goto webview2_done
  470. install_webview2:
  471. DetailPrint "$(installingWebview2)"
  472. ; $6 holds the path to the webview2 installer
  473. ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1
  474. ${If} $1 == 0
  475. DetailPrint "$(webview2InstallSuccess)"
  476. ${Else}
  477. DetailPrint "$(webview2InstallError)"
  478. Abort "$(webview2AbortError)"
  479. ${EndIf}
  480. webview2_done:
  481. SectionEnd
  482. !macro CheckIfAppIsRunning
  483. !if "${INSTALLMODE}" == "currentUser"
  484. nsis_tauri_utils::FindProcessCurrentUser "${MAINBINARYNAME}.exe"
  485. !else
  486. nsis_tauri_utils::FindProcess "${MAINBINARYNAME}.exe"
  487. !endif
  488. Pop $R0
  489. ${If} $R0 = 0
  490. IfSilent kill 0
  491. ${IfThen} $PassiveMode != 1 ${|} MessageBox MB_OKCANCEL "$(appRunningOkKill)" IDOK kill IDCANCEL cancel ${|}
  492. kill:
  493. !if "${INSTALLMODE}" == "currentUser"
  494. nsis_tauri_utils::KillProcessCurrentUser "${MAINBINARYNAME}.exe"
  495. !else
  496. nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
  497. !endif
  498. Pop $R0
  499. Sleep 500
  500. ${If} $R0 = 0
  501. Goto app_check_done
  502. ${Else}
  503. IfSilent silent ui
  504. silent:
  505. System::Call 'kernel32::AttachConsole(i -1)i.r0'
  506. ${If} $0 != 0
  507. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  508. System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color
  509. FileWrite $0 "$(appRunning)$\n"
  510. ${EndIf}
  511. Abort
  512. ui:
  513. Abort "$(failedToKillApp)"
  514. ${EndIf}
  515. cancel:
  516. Abort "$(appRunning)"
  517. ${EndIf}
  518. app_check_done:
  519. !macroend
  520. Section Install
  521. SetOutPath $INSTDIR
  522. !insertmacro CheckIfAppIsRunning
  523. !insertmacro CheckAllVergeProcesses
  524. ; Copy main executable
  525. File "${MAINBINARYSRCPATH}"
  526. ; Copy resources
  527. {{#each resources_dirs}}
  528. CreateDirectory "$INSTDIR\\{{this}}"
  529. {{/each}}
  530. {{#each resources}}
  531. File /a "/oname={{this.[1]}}" "{{@key}}"
  532. {{/each}}
  533. ; Copy external binaries
  534. {{#each binaries}}
  535. File /a "/oname={{this}}" "{{@key}}"
  536. {{/each}}
  537. ; Create uninstaller
  538. WriteUninstaller "$INSTDIR\uninstall.exe"
  539. ; Save $INSTDIR in registry for future installations
  540. WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR
  541. !if "${INSTALLMODE}" == "both"
  542. ; Save install mode to be selected by default for the next installation such as updating
  543. ; or when uninstalling
  544. WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1
  545. !endif
  546. ; Registry information for add/remove programs
  547. WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}"
  548. WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\""
  549. WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}"
  550. WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}"
  551. WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\""
  552. WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
  553. WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1"
  554. WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1"
  555. WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "${ESTIMATEDSIZE}"
  556. ; Create start menu shortcut (GUI)
  557. !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
  558. Call CreateStartMenuShortcut
  559. !insertmacro MUI_STARTMENU_WRITE_END
  560. ; Create shortcuts for silent and passive installers, which
  561. ; can be disabled by passing `/NS` flag
  562. ; GUI installer has buttons for users to control creating them
  563. IfSilent check_ns_flag 0
  564. ${IfThen} $PassiveMode == 1 ${|} Goto check_ns_flag ${|}
  565. Goto shortcuts_done
  566. check_ns_flag:
  567. ${GetOptions} $CMDLINE "/NS" $R0
  568. IfErrors 0 shortcuts_done
  569. Call CreateDesktopShortcut
  570. Call CreateStartMenuShortcut
  571. shortcuts_done:
  572. ; Auto close this page for passive mode
  573. ${IfThen} $PassiveMode == 1 ${|} SetAutoClose true ${|}
  574. SectionEnd
  575. Function .onInstSuccess
  576. ; Check for `/R` flag only in silent and passive installers because
  577. ; GUI installer has a toggle for the user to (re)start the app
  578. IfSilent check_r_flag 0
  579. ${IfThen} $PassiveMode == 1 ${|} Goto check_r_flag ${|}
  580. Goto run_done
  581. check_r_flag:
  582. ${GetOptions} $CMDLINE "/R" $R0
  583. IfErrors run_done 0
  584. Exec '"$INSTDIR\${MAINBINARYNAME}.exe"'
  585. run_done:
  586. FunctionEnd
  587. Function un.onInit
  588. !insertmacro SetContext
  589. !if "${INSTALLMODE}" == "both"
  590. !insertmacro MULTIUSER_UNINIT
  591. !endif
  592. !insertmacro MUI_UNGETLANGUAGE
  593. FunctionEnd
  594. Section Uninstall
  595. !insertmacro CheckIfAppIsRunning
  596. !insertmacro CheckAllVergeProcesses
  597. ; Delete the app directory and its content from disk
  598. ; Copy main executable
  599. Delete "$INSTDIR\${MAINBINARYNAME}.exe"
  600. ; Delete resources
  601. {{#each resources}}
  602. Delete "$INSTDIR\\{{this.[1]}}"
  603. {{/each}}
  604. ; Delete external binaries
  605. {{#each binaries}}
  606. Delete "$INSTDIR\\{{this}}"
  607. {{/each}}
  608. ; Delete uninstaller
  609. Delete "$INSTDIR\uninstall.exe"
  610. ${If} $DeleteAppDataCheckboxState == 1
  611. RMDir /R /REBOOTOK "$INSTDIR"
  612. ${Else}
  613. {{#each resources_ancestors}}
  614. RMDir /REBOOTOK "$INSTDIR\\{{this}}"
  615. {{/each}}
  616. RMDir "$INSTDIR"
  617. ${EndIf}
  618. ; Remove start menu shortcut
  619. !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder
  620. Delete "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk"
  621. RMDir "$SMPROGRAMS\$AppStartMenuFolder"
  622. ; Remove desktop shortcuts
  623. Delete "$DESKTOP\${MAINBINARYNAME}.lnk"
  624. ; Remove registry information for add/remove programs
  625. !if "${INSTALLMODE}" == "both"
  626. DeleteRegKey SHCTX "${UNINSTKEY}"
  627. !else if "${INSTALLMODE}" == "perMachine"
  628. DeleteRegKey HKLM "${UNINSTKEY}"
  629. !else
  630. DeleteRegKey HKCU "${UNINSTKEY}"
  631. !endif
  632. DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language"
  633. ; Delete app data
  634. ${If} $DeleteAppDataCheckboxState == 1
  635. SetShellVarContext current
  636. RmDir /r "$APPDATA\${BUNDLEID}"
  637. RmDir /r "$LOCALAPPDATA\${BUNDLEID}"
  638. ${EndIf}
  639. ${GetOptions} $CMDLINE "/P" $R0
  640. IfErrors +2 0
  641. SetAutoClose true
  642. SectionEnd
  643. Function RestorePreviousInstallLocation
  644. ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" ""
  645. StrCmp $4 "" +2 0
  646. StrCpy $INSTDIR $4
  647. FunctionEnd
  648. Function SkipIfPassive
  649. ${IfThen} $PassiveMode == 1 ${|} Abort ${|}
  650. FunctionEnd
  651. Function CreateDesktopShortcut
  652. CreateShortcut "$DESKTOP\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
  653. ApplicationID::Set "$DESKTOP\${MAINBINARYNAME}.lnk" "${BUNDLEID}"
  654. FunctionEnd
  655. Function CreateStartMenuShortcut
  656. CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder"
  657. CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
  658. ApplicationID::Set "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "${BUNDLEID}"
  659. FunctionEnd