jellyfin.nsi 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. ; Shows a lot of debug information while compiling
  2. ; This can be removed once stable.
  3. !verbose 4
  4. ;--------------------------------
  5. !define SF_USELECTED 0 ; used to check selected options status, rest are inherited from Sections.nsh
  6. !include "MUI2.nsh"
  7. !include "Sections.nsh"
  8. !include "LogicLib.nsh"
  9. ; Global variables that we'll use
  10. Var _JELLYFINVERSION_
  11. Var _JELLYFINDATADIR_
  12. Var _INSTALLSERVICE_
  13. Var _SERVICESTART_
  14. Var _LOCALSYSTEMACCOUNT_
  15. Var _EXISTINGINSTALLATION_
  16. Var _EXISTINGSERVICE_
  17. Var _CUSTOMDATAFOLDER_
  18. !if ${NSIS_PTR_SIZE} > 4
  19. !define BITS 64
  20. !define NAMESUFFIX " (64 bit)"
  21. !else
  22. !define BITS 32
  23. !define NAMESUFFIX ""
  24. !endif
  25. ;--------------------------------
  26. !define REG_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" ;Registry to show up in Add/Remove Programs
  27. !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ ;Align installer version with jellyfin.dll version
  28. Name "Jellyfin Server ${ver_1}.${ver_2}.${ver_3}" ; This is referred in various header text labels
  29. OutFile "jellyfin_${ver_1}.${ver_2}.${ver_3}_windows.exe" ; Naming convention jellyfin_{version}_windows-{arch].exe
  30. BrandingText "Jellyfin Server ${ver_1}.${ver_2}.${ver_3} Installer" ; This shows in just over the buttons
  31. ; installer attributes, these show up in details tab on installer properties
  32. VIProductVersion "${ver_1}.${ver_2}.${ver_3}.0" ; VIProductVersion format, should be X.X.X.X
  33. VIFileVersion "${ver_1}.${ver_2}.${ver_3}.0" ; VIFileVersion format, should be X.X.X.X
  34. VIAddVersionKey "ProductName" "Jellyfin Server"
  35. VIAddVersionKey "FileVersion" "${ver_1}.${ver_2}.${ver_3}.0"
  36. VIAddVersionKey "LegalCopyright" "Jellyfin, Free Software Media System"
  37. VIAddVersionKey "FileDescription" "Jellyfin Server"
  38. ;TODO, check defaults
  39. InstallDir "$PROGRAMFILES\Jellyfin" ;Default installation folder
  40. InstallDirRegKey HKLM "Software\Jellyfin" "InstallFolder" ;Read the registry for install folder,
  41. RequestExecutionLevel admin ; ask it upfront for service control, and installing in priv folders
  42. CRCCheck on ; make sure the installer wasn't corrupted while downloading
  43. !define MUI_ABORTWARNING ;Prompts user in case of aborting install
  44. ; TODO: Replace with nice Jellyfin Icons
  45. !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-install.ico" ; Installer Icon
  46. !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico" ; Uninstaller Icon
  47. !define MUI_HEADERIMAGE
  48. !define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\nsis3-branding.bmp"
  49. !define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\nsis3-branding.bmp"
  50. ;--------------------------------
  51. ;Pages
  52. ; Welcome Page
  53. !define MUI_WELCOMEPAGE_TEXT "The installer will ask for details to install Jellyfin Server.$\r$\n$\r$\n$\r$\n\
  54. ADVANCED:$\r$\n\
  55. The default service install uses Network Service account and is sufficient for most users. $\r$\n$\r$\n\
  56. You can choose to install using Local System account under Advanced options. This also affects where Jellyfin Server and Jellyfin data can be installed. The installer will NOT check this, you should know what you are doing.$\r$\n$\r$\n\
  57. You can choose the folder for Jellyfin Metadata under advanced options based on your needs."
  58. !insertmacro MUI_PAGE_WELCOME
  59. ; License Page
  60. !insertmacro MUI_PAGE_LICENSE "$%InstallLocation%\LICENSE" ; picking up generic GPL
  61. ; Components Page
  62. !define MUI_COMPONENTSPAGE_SMALLDESC
  63. !insertmacro MUI_PAGE_COMPONENTS
  64. !define MUI_PAGE_CUSTOMFUNCTION_PRE HideInstallDirectoryPage ; Controls when to hide / show
  65. !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Install folder" ; shows just above the folder selection dialog
  66. !insertmacro MUI_PAGE_DIRECTORY
  67. ; Metadata folder Page
  68. !define MUI_PAGE_CUSTOMFUNCTION_PRE HideDataDirectoryPage ; Controls when to hide / show
  69. !define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install the Jellyfin Server metadata."
  70. !define MUI_DIRECTORYPAGE_TEXT_TOP "The installer will set the following folder for Jellyfin Server metadata. To install in a differenct folder, click Browse and select another folder. Please make sure the folder exists. Click Next to continue."
  71. !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Metadata folder"
  72. !define MUI_DIRECTORYPAGE_VARIABLE $_JELLYFINDATADIR_
  73. !insertmacro MUI_PAGE_DIRECTORY
  74. ; Confirmation Page
  75. Page custom ConfirmationPage ; just letting the user know what they chose to install
  76. ; Actual Installion Page
  77. !insertmacro MUI_PAGE_INSTFILES
  78. !insertmacro MUI_UNPAGE_CONFIRM
  79. !insertmacro MUI_UNPAGE_INSTFILES
  80. !insertmacro MUI_UNPAGE_FINISH
  81. ;--------------------------------
  82. ;Languages; Add more languages later here if needed
  83. !insertmacro MUI_LANGUAGE "English"
  84. ;--------------------------------
  85. ;Installer Sections
  86. Section "Jellyfin Server (required)" InstallJellyfin
  87. SectionIn RO ; Mandatory section, isn't this the whole purpose to run the installer.
  88. StrCmp "$_EXISTINGINSTALLATION_" "YES" RunUninstaller CarryOn ; Silently uninstall in case of previous installation
  89. RunUninstaller:
  90. DetailPrint "Looking for uninstaller at $INSTDIR"
  91. FindFirst $0 $1 "$INSTDIR\Uninstall.exe"
  92. FindClose $0
  93. StrCmp $1 "" CarryOn ; the registry key was there but uninstaller was not found
  94. DetailPrint "Silently running the uninstaller at $INSTDIR"
  95. ExecWait '"$INSTDIR\Uninstall.exe" /S _?=$INSTDIR' $0
  96. DetailPrint "Uninstall finished, $0"
  97. CarryOn:
  98. SetOutPath "$INSTDIR"
  99. File /r $%InstallLocation%\*
  100. ; Write the InstallFolder, DataFolder, Network Service info into the registry for later use
  101. WriteRegExpandStr HKLM "Software\Jellyfin" "InstallFolder" "$INSTDIR"
  102. WriteRegExpandStr HKLM "Software\Jellyfin" "DataFolder" "$_JELLYFINDATADIR_"
  103. WriteRegStr HKLM "Software\Jellyfin" "LocalSystemAccount" "$_LOCALSYSTEMACCOUNT_"
  104. !getdllversion "$%InstallLocation%\jellyfin.dll" ver_
  105. StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}" ;
  106. ; Write the uninstall keys for Windows
  107. WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayName" "Jellyfin $_JELLYFINVERSION_"
  108. WriteRegExpandStr HKLM "${REG_UNINST_KEY}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
  109. WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayIcon" '"$INSTDIR\Jellyfin.exe",0'
  110. WriteRegStr HKLM "${REG_UNINST_KEY}" "Publisher" "The Jellyfin project"
  111. WriteRegStr HKLM "${REG_UNINST_KEY}" "URLInfoAbout" "https://jellyfin.github.io/"
  112. WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayVersion" "$_JELLYFINVERSION_"
  113. WriteRegDWORD HKLM "${REG_UNINST_KEY}" "NoModify" 1
  114. WriteRegDWORD HKLM "${REG_UNINST_KEY}" "NoRepair" 1
  115. ;Create uninstaller
  116. WriteUninstaller "$INSTDIR\Uninstall.exe"
  117. SectionEnd
  118. Section "Jellyfin Service" InstallService
  119. ExecWait '"$INSTDIR\nssm.exe" install Jellyfin "$INSTDIR\jellyfin.exe" --datadir "$_JELLYFINDATADIR_"' $0
  120. DetailPrint "Jellyfin Service install, $0"
  121. Sleep 3000 ; Give time for Windows to catchup
  122. ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START' $0
  123. DetailPrint "Jellyfin Service setting, $0"
  124. Sleep 3000
  125. ${If} $_LOCALSYSTEMACCOUNT_ == "NO" ; the default install using NSSM is Local System
  126. DetailPrint "Attempting to change service account to Network Service"
  127. ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Objectname "Network Service"' $0
  128. DetailPrint "Jellyfin service account change, $0"
  129. ${EndIf}
  130. SectionEnd
  131. Section "Start Jellyfin service after install" StartService
  132. ExecWait '"$INSTDIR\nssm.exe" start Jellyfin' $0
  133. DetailPrint "Jellyfin service start, $0"
  134. SectionEnd
  135. SectionGroup "Advanced" Advanced
  136. Section /o "Use Local System account" LocalSystemAccount
  137. ; The section is for user choice, nothing to do here
  138. SectionEnd
  139. Section /o "Custom Jellyfin metadata folder" CustomDataFolder
  140. ; The section is for user choice, nothing to do here
  141. SectionEnd
  142. SectionGroupEnd
  143. ;--------------------------------
  144. ;Descriptions
  145. ;Language strings
  146. LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin Server"
  147. LangString DESC_InstallService ${LANG_ENGLISH} "Install As a Service"
  148. LangString DESC_StartService ${LANG_ENGLISH} "Start Jellyfin service after Install"
  149. LangString DESC_LocalSystemAccount ${LANG_ENGLISH} "Use Local System account to start windows service"
  150. LangString DESC_CustomDataFolder ${LANG_ENGLISH} "Choose Jellyfin Server metadata folder in subsequent steps"
  151. ;Assign language strings to sections
  152. !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  153. !insertmacro MUI_DESCRIPTION_TEXT ${InstallJellyfin} $(DESC_InstallJellyfin)
  154. !insertmacro MUI_DESCRIPTION_TEXT ${InstallService} $(DESC_InstallService)
  155. !insertmacro MUI_DESCRIPTION_TEXT ${StartService} $(DESC_StartService)
  156. !insertmacro MUI_DESCRIPTION_TEXT ${LocalSystemAccount} $(DESC_LocalSystemAccount)
  157. !insertmacro MUI_DESCRIPTION_TEXT ${CustomDataFolder} $(DESC_CustomDataFolder)
  158. !insertmacro MUI_FUNCTION_DESCRIPTION_END
  159. ;--------------------------------
  160. ;Uninstaller Section
  161. Section "Uninstall"
  162. ReadRegStr $INSTDIR HKLM "Software\Jellyfin" "InstallFolder" ; read the installation folder
  163. ReadRegStr $_JELLYFINDATADIR_ HKLM "Software\Jellyfin" "DataFolder" ; read the metadata folder
  164. DetailPrint "Jellyfin Install location : $INSTDIR"
  165. DetailPrint "Jellyfin data folder : $_JELLYFINDATADIR_"
  166. MessageBox MB_YESNO|MB_ICONINFORMATION "Do you want to retain Jellyfin metadata folder? The media will not be touched. $\r$\nIf unsure choose YES." /SD IDYES IDYES PreserveData
  167. RMDir /r /REBOOTOK "$_JELLYFINDATADIR_"
  168. PreserveData:
  169. DetailPrint "Attempting to stop Jellyfin Server"
  170. ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0
  171. DetailPrint "Jellyfin service stop, $0"
  172. DetailPrint "Attempting to remove Jellyfin service"
  173. ExecWait '"$INSTDIR\nssm.exe" remove Jellyfin confirm' $0
  174. DetailPrint "Jellyfin Service remove, $0"
  175. Delete "$INSTDIR\Uninstall.exe"
  176. RMDir /r /REBOOTOK "$INSTDIR"
  177. DeleteRegKey HKLM "Software\Jellyfin"
  178. DeleteRegKey HKLM "${REG_UNINST_KEY}"
  179. SectionEnd
  180. Function .onInit
  181. ; Setting up defaults
  182. StrCpy $_INSTALLSERVICE_ "YES"
  183. StrCpy $_SERVICESTART_ "YES"
  184. StrCpy $_CUSTOMDATAFOLDER_ "NO"
  185. StrCpy $_LOCALSYSTEMACCOUNT_ "NO"
  186. StrCpy $_EXISTINGINSTALLATION_ "NO"
  187. StrCpy $_EXISTINGSERVICE_ "NO"
  188. SetShellVarContext current
  189. StrCpy $_JELLYFINDATADIR_ "$%ProgramData%\jellyfin\"
  190. ;Detect if Jellyfin is already installed.
  191. ; In case it is installed, let the user choose either
  192. ; 1. Exit installer
  193. ; 2. Upgrade without messing with data
  194. ; 2a. Don't ask for any details, uninstall and install afresh with old settings
  195. ; Read Registry for previous installation
  196. ClearErrors
  197. ReadRegStr "$0" HKLM "Software\Jellyfin" "InstallFolder"
  198. IfErrors NoExisitingInstall
  199. DetailPrint "Existing Jellyfin detected at: $0"
  200. StrCpy "$INSTDIR" "$0" ; set the location fro registry as new default
  201. StrCpy $_EXISTINGINSTALLATION_ "YES" ; Set our flag to be used later
  202. SectionSetText ${InstallJellyfin} "Upgrade Jellyfin Server(required)" ; Change install text to "Upgrade"
  203. ; check if there is a service called Jellyfin, there should be
  204. ; hack : nssm statuscode Jellyfin will return non zero return code in case it exists
  205. ExecWait '"$INSTDIR\nssm.exe" statuscode Jellyfin' $0
  206. DetailPrint "Jellyfin service statuscode, $0"
  207. IntCmp $0 0 NoService ; service doesn't exist, may be run from desktop shortcut
  208. ; if service was detected, set defaults going forward.
  209. StrCpy $_EXISTINGSERVICE_ "YES"
  210. StrCpy $_INSTALLSERVICE_ "YES"
  211. StrCpy $_SERVICESTART_ "YES"
  212. ; check if service was run using Network Service account
  213. ClearErrors
  214. ReadRegStr "$_LOCALSYSTEMACCOUNT_" HKLM "Software\Jellyfin" "LocalSystemAccount" ; in case of error _LOCALSYSTEMACCOUNT_ will be NO as default
  215. ClearErrors
  216. ReadRegStr $_JELLYFINDATADIR_ HKLM "Software\Jellyfin" "DataFolder" ; in case of error, the default holds
  217. ; Hide sections which will not be needed in case of previous install
  218. SectionSetText ${InstallService} ""
  219. SectionSetText ${StartService} ""
  220. SectionSetText ${LocalSystemAccount} ""
  221. SectionSetText ${CustomDataFolder} ""
  222. SectionSetText ${Advanced} ""
  223. NoService: ; existing install was present but no service was detected
  224. ; Let the user know that we'll upgrade and provide an option to quit.
  225. MessageBox MB_OKCANCEL|MB_ICONINFORMATION "Existing installation of Jellyfin was detected, it'll be upgraded, settings will be retained. \
  226. $\r$\nClick OK to proceed, Cancel to exit installer." /SD IDOK IDOK ProceedWithUpgrade
  227. Quit ; Quit if the user is not sure about upgrade
  228. ProceedWithUpgrade:
  229. NoExisitingInstall:
  230. ; by this time, the variables have been correctly set to reflect previous install details
  231. FunctionEnd
  232. Function HideInstallDirectoryPage
  233. ${If} $_EXISTINGINSTALLATION_ == "YES" ; Existing installation detected, so don't ask for InstallFolder
  234. Abort
  235. ${EndIf}
  236. FunctionEnd
  237. ; Don't show custom folder option in case it wasn't chosen
  238. Function HideDataDirectoryPage
  239. ${If} $_CUSTOMDATAFOLDER_ == "NO"
  240. Abort
  241. ${EndIf}
  242. FunctionEnd
  243. ; This function handles the choices during component selection
  244. Function .onSelChange
  245. SectionGetFlags ${CustomDataFolder} $0
  246. ${If} $0 = ${SF_SELECTED}
  247. StrCpy $_CUSTOMDATAFOLDER_ "YES"
  248. ${Else}
  249. StrCpy $_CUSTOMDATAFOLDER_ "NO"
  250. ${EndIf}
  251. ; If we are not installing service, we don't need to set the NetworkService account or StartService
  252. SectionGetFlags ${InstallService} $0
  253. ${If} $0 = ${SF_SELECTED}
  254. StrCpy $_INSTALLSERVICE_ "YES"
  255. SectionGetFlags ${LocalSystemAccount} $0
  256. IntOp $0 $0 | ${SF_RO}
  257. IntOp $0 $0 ^ ${SF_RO}
  258. SectionSetFlags ${LocalSystemAccount} $0
  259. SectionGetFlags ${StartService} $0
  260. IntOp $0 $0 | ${SF_RO}
  261. IntOp $0 $0 ^ ${SF_RO}
  262. SectionSetFlags ${StartService} $0
  263. ${Else}
  264. StrCpy $_INSTALLSERVICE_ "NO"
  265. IntOp $0 ${SF_USELECTED} | ${SF_RO}
  266. SectionSetFlags ${LocalSystemAccount} $0
  267. SectionSetFlags ${StartService} $0
  268. ${EndIf}
  269. SectionGetFlags ${StartService} $0
  270. ${If} $0 = ${SF_SELECTED}
  271. StrCpy $_SERVICESTART_ "YES"
  272. ${Else}
  273. StrCpy $_SERVICESTART_ "NO"
  274. ${EndIf}
  275. SectionGetFlags ${LocalSystemAccount} $0
  276. ${If} $0 = ${SF_SELECTED}
  277. StrCpy $_LOCALSYSTEMACCOUNT_ "YES"
  278. ${Else}
  279. StrCpy $_LOCALSYSTEMACCOUNT_ "NO"
  280. ${EndIf}
  281. FunctionEnd
  282. Function ConfirmationPage
  283. !insertmacro MUI_HEADER_TEXT "Confirmation Page" "Please confirm your choices for Jellyfin Server installation"
  284. nsDialogs::Create 1018
  285. ${NSD_CreateLabel} 0 0 100% 100% "The installer will proceed based on the following inputs gathered on earlier screens.$\r$\n$\r$\n\
  286. Installation Folder : $INSTDIR$\r$\n\
  287. Service install : $_INSTALLSERVICE_$\r$\n\
  288. Service start : $_SERVICESTART_$\r$\n\
  289. Local System account for service: $_LOCALSYSTEMACCOUNT_$\r$\n\
  290. Custom Metadata folder : $_CUSTOMDATAFOLDER_$\r$\n\
  291. Jellyfin Metadata Folder: $_JELLYFINDATADIR_"
  292. nsDialogs::Show
  293. FunctionEnd
  294. Function .onInstSuccess
  295. ExecShell "open" "http://localhost:8096"
  296. FunctionEnd