From 3b9766f58c15f6300a99151f9064775deccb66a3 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 11:41:33 +1000 Subject: [PATCH 01/15] Added option for NSIS This change will 1. download NSIS zip, 2. unzip in temp folder, 3. use nsis to build the installer --- deployment/windows/build-jellyfin.ps1 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index 2999912b3a..bac907047a 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -1,5 +1,6 @@ [CmdletBinding()] param( + [switch]$MakeNSIS, [switch]$InstallFFMPEG, [switch]$InstallNSSM, [switch]$GenerateZip, @@ -96,6 +97,23 @@ function Install-NSSM { Remove-Item "$tempdir/nssm.zip" -Force -ErrorAction Continue | Write-Verbose } +function Make-NSIS { + param( + [string]$InstallLocation + ) + Write-Verbose "Downloading NSIS" + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest -Uri https://nchc.dl.sourceforge.net/project/nsis/NSIS%203/3.04/nsis-3.04.zip -UseBasicParsing -OutFile "$tempdir/nsis.zip" | Write-Verbose + + Expand-Archive "$tempdir/nsis.zip" -DestinationPath "$tempdir/nsis/" | Write-Verbose + $env:InstallLocation = $InstallLocation + & "$tempdir/nsis/nsis-3.04/makensis.exe" ".\deployment\windows\jellyfin.nsi" + Copy-Item .\deployment\windows\Jellyfin.Installer.*.exe $InstallLocation\..\ + + Remove-Item "$tempdir/nsis/" -Recurse -Force -ErrorAction Continue | Write-Verbose + Remove-Item "$tempdir/nsis.zip" -Force -ErrorAction Continue | Write-Verbose +} + Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture" Build-JellyFin if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){ @@ -106,6 +124,10 @@ if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){ Write-Verbose "Starting NSSM Install" Install-NSSM $InstallLocation $Architecture } +if($MakeNSIS.IsPresent -or ($MakeNSIS -eq $true)){ + Write-Verbose "Starting NSIS Package creation" + Make-NSIS $InstallLocation +} Copy-Item .\deployment\windows\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 Copy-Item .\deployment\windows\install.bat $InstallLocation\install.bat if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){ From 1fd827fa775e706704ef976f5b8d179416df41a6 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 11:43:20 +1000 Subject: [PATCH 02/15] Create jellyfin.nsi --- deployment/windows/jellyfin.nsi | 185 ++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 deployment/windows/jellyfin.nsi diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi new file mode 100644 index 0000000000..b4a927610a --- /dev/null +++ b/deployment/windows/jellyfin.nsi @@ -0,0 +1,185 @@ +!verbose 4 +;-------------------------------- +;Include Modern UI + + !include "MUI2.nsh" + Var JellyfinVersion + Var defaultEmbyDataDir + Var JELLYFINDATADIR + Var ServiceInstalled +;-------------------------------- +;General + + ;Name and file + !getdllversion "$%InstallLocation%\jellyfin.dll" expv_ + !echo "jellyfin.dll version is ${expv_1}.${expv_2}.${expv_3}.${expv_4}" + Name "Jellyfin ${expv_1}.${expv_2}.${expv_3}.${expv_4}" + OutFile "Jellyfin.Installer.${expv_1}.${expv_2}.${expv_3}.${expv_4}.exe" + BrandingText "Jellyfin ${expv_1}.${expv_2}.${expv_3}.${expv_4} Installer" + VIProductVersion "${expv_1}.${expv_2}.${expv_3}.${expv_4}" + VIFileVersion "${expv_1}.${expv_2}.${expv_3}.${expv_4}" + VIAddVersionKey "ProductName" "Jellyfin" + VIAddVersionKey "FileVersion" "${expv_1}.${expv_2}.${expv_3}.${expv_4}" + + ;Default installation folder + InstallDir "$APPDATA\Jellyfin" + + ;Get installation folder from registry if available + InstallDirRegKey HKLM "Software\Jellyfin" "InstallLocation" + + ;Request application privileges for Windows Vista + RequestExecutionLevel admin + CRCCheck on + !define MUI_ABORTWARNING + +;-------------------------------- +;Pages + +; !insertmacro MUI_PAGE_LICENSE "${NSISDIR}\Docs\Modern UI\License.txt" + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + + !define MUI_PAGE_HEADER_TEXT "MUI_PAGE_HEADER_TEXT" + !define MUI_PAGE_HEADER_SUBTEXT "MUI_PAGE_HEADER_SUBTEXT" + !define MUI_DIRECTORYPAGE_TEXT_TOP "MUI_DIRECTORYPAGE_TEXT_TOP" + !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "APP Folder" + !define MUI_PAGE_CUSTOMFUNCTION_PRE ShowEmbyLibraryPage + !define MUI_DIRECTORYPAGE_VARIABLE $defaultEmbyDataDir + !insertmacro MUI_PAGE_DIRECTORY + + + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + + +;-------------------------------- +;Installer Sections + +Section "Install Jellyfin (required)" InstallJellyfin + SetOutPath "$INSTDIR" +;Create uninstaller + + File /r $%InstallLocation%\* +; Write the installation path into the registry + WriteRegStr HKLM "Software\Jellyfin" "InstallLocation" "$INSTDIR" + +; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayName" "Jellyfin $JellyfinVersion" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayIcon" '"$INSTDIR\Jellyfin.exe",0' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "Publisher" "The Jellyfin project" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "URLInfoAbout" "https://jellyfin.github.io/" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayVersion" "$JellyfinVersion" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "NoRepair" 1 + WriteUninstaller "$INSTDIR\Uninstall.exe" + +SectionEnd + + +Section "Jellyfin Service" InstallService + ExecWait '"$INSTDIR"\nssm.exe install Jellyfin "$INSTDIR"\jellyfin.exe --datadir "$JELLYFINDATADIR"' $0 + MessageBox MB_OK "Service install Error : $0" + Sleep 3000 + ExecWait '"$INSTDIR"\nssm.exe set Jellyfin Start SERVICE_DELAYED_AUTO_START' $0 + MessageBox MB_OK "Service setting Error : $0" + StrCpy $ServiceInstalled "YES" +SectionEnd + +Section "Desktop shortcut" DesktopShortcut + SetShellVarContext current + CreateShortCut "$DESKTOP\Jellyfin.lnk" "$INSTDIR\jellyfin.exe" +SectionEnd + +;TODO +Section "Launch Jellyfin" LaunchJellyfin + !echo "Binaries at : $%InstallLocation%" +; either start the service or launch jellyfin standalone + StrCmp $ServiceInstalled "YES" ServiceStart Standalone + + ServiceStart: + ExecWait 'C:\Windows\System32\sc.exe start Jellyfin' $0 + MessageBox MB_OK "Service start Error : $0" + Return + + Standalone: + ExecWait '"$INSTDIR"\jellyfin.exe' $0 + MessageBox MB_OK "start Error : $0" + +SectionEnd + +;TODO +Section "Migrate Emby Library" MigrateEmbyLibrary + + CopyFiles $defaultEmbyDataDir/config $JELLYFINDATADIR + CopyFiles $defaultEmbyDataDir/cache $JELLYFINDATADIR + CopyFiles $defaultEmbyDataDir/data $JELLYFINDATADIR + CopyFiles $defaultEmbyDataDir/metadata $JELLYFINDATADIR + CopyFiles $defaultEmbyDataDir/root $JELLYFINDATADIR + +SectionEnd + + +;-------------------------------- +;Descriptions + + ;Language strings + LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin" + LangString DESC_InstallService ${LANG_ENGLISH} "Install As a Service" + LangString DESC_DesktopShortcut ${LANG_ENGLISH} "Create a desktop shortcut" + LangString DESC_LaunchJellyfin ${LANG_ENGLISH} "Start Jellyfin after Install" + LangString DESC_MigrateEmbyLibrary ${LANG_ENGLISH} "Migrate existing Emby Library" + + ;Assign language strings to sections + !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${InstallJellyfin} $(DESC_InstallJellyfin) + !insertmacro MUI_DESCRIPTION_TEXT ${InstallService} $(DESC_InstallService) + !insertmacro MUI_DESCRIPTION_TEXT ${LaunchJellyfin} $(DESC_LaunchJellyfin) + !insertmacro MUI_DESCRIPTION_TEXT ${MigrateEmbyLibrary} $(DESC_MigrateEmbyLibrary) + !insertmacro MUI_FUNCTION_DESCRIPTION_END + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + +;TODO +; stop service or running instance + MessageBox MB_OK "uninstall $INSTDIR, $JELLYFINDATADIR" + + Delete "$INSTDIR\Uninstall.exe" + RMDir /r "$INSTDIR" + RMDir /r "$JELLYFINDATADIR" + DeleteRegKey HKLM "Software\Jellyfin" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" + Delete "$DESKTOP\Jellyfin.lnk" + +SectionEnd + + +Function .onInit + SetShellVarContext all + !getdllversion "$%InstallLocation%\jellyfin.dll" expv_ + StrCpy $JellyfinVersion "${expv_1}.${expv_2}.${expv_3}.${expv_4}" + StrCpy $JELLYFINDATADIR "$LOCALAPPDATA\jellyfin\" + StrCpy $ServiceInstalled "NO" + SectionSetFlags ${InstallJellyfin} 17 +FunctionEnd + +Function ShowEmbyLibraryPage + SectionGetFlags ${MigrateEmbyLibrary} $R0 + IntOp $R0 $R0 & ${SF_SELECTED} + IntCmp $R0 ${SF_SELECTED} show + + Abort ; Dont show the Emby folder selection window if Emby migrartion is not selected + + show: +FunctionEnd From 43989800baa4e147a67c4b278e05face3ceadb5f Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 12:16:34 +1000 Subject: [PATCH 03/15] Added -Force to nsis extraction --- deployment/windows/build-jellyfin.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index bac907047a..0cfd78dfa5 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -30,7 +30,7 @@ function Build-JellyFin { Write-Verbose "windowsversion-Architecture: $windowsversion-$Architecture" Write-Verbose "InstallLocation: $InstallLocation" Write-Verbose "DotNetVerbosity: $DotNetVerbosity" - dotnet publish -c $BuildType -r `"$windowsversion-$Architecture`" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity +# dotnet publish -c $BuildType -r `"$windowsversion-$Architecture`" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity } function Install-FFMPEG { @@ -105,7 +105,7 @@ function Make-NSIS { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri https://nchc.dl.sourceforge.net/project/nsis/NSIS%203/3.04/nsis-3.04.zip -UseBasicParsing -OutFile "$tempdir/nsis.zip" | Write-Verbose - Expand-Archive "$tempdir/nsis.zip" -DestinationPath "$tempdir/nsis/" | Write-Verbose + Expand-Archive "$tempdir/nsis.zip" -DestinationPath "$tempdir/nsis/" -Force | Write-Verbose $env:InstallLocation = $InstallLocation & "$tempdir/nsis/nsis-3.04/makensis.exe" ".\deployment\windows\jellyfin.nsi" Copy-Item .\deployment\windows\Jellyfin.Installer.*.exe $InstallLocation\..\ @@ -114,6 +114,7 @@ function Make-NSIS { Remove-Item "$tempdir/nsis.zip" -Force -ErrorAction Continue | Write-Verbose } + Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture" Build-JellyFin if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){ From de9ee10abc8d0401f11dc5efed7adc4d36695db8 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 12:18:20 +1000 Subject: [PATCH 04/15] Uncomment accidental commenting of compilation --- deployment/windows/build-jellyfin.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index 0cfd78dfa5..7b04c93103 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -30,7 +30,7 @@ function Build-JellyFin { Write-Verbose "windowsversion-Architecture: $windowsversion-$Architecture" Write-Verbose "InstallLocation: $InstallLocation" Write-Verbose "DotNetVerbosity: $DotNetVerbosity" -# dotnet publish -c $BuildType -r `"$windowsversion-$Architecture`" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity + dotnet publish -c $BuildType -r `"$windowsversion-$Architecture`" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity } function Install-FFMPEG { From a6819ffd1d7ed36f88316d7bfe82cf2e1979bd68 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 12:19:57 +1000 Subject: [PATCH 05/15] Cleaned up code --- deployment/windows/jellyfin.nsi | 118 ++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index b4a927610a..6187cf9fdd 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -1,25 +1,30 @@ +; Shows a lot of debug information while compiling +; This can be removed once stable. !verbose 4 ;-------------------------------- ;Include Modern UI !include "MUI2.nsh" - Var JellyfinVersion - Var defaultEmbyDataDir - Var JELLYFINDATADIR - Var ServiceInstalled + Var _JELLYFINVERSION_ + Var _DEFAULTEMBYDATADIR_ + Var _JELLYFINDATADIR_ + Var _SERVICEINSTALLED_ ;-------------------------------- ;General - ;Name and file - !getdllversion "$%InstallLocation%\jellyfin.dll" expv_ - !echo "jellyfin.dll version is ${expv_1}.${expv_2}.${expv_3}.${expv_4}" - Name "Jellyfin ${expv_1}.${expv_2}.${expv_3}.${expv_4}" - OutFile "Jellyfin.Installer.${expv_1}.${expv_2}.${expv_3}.${expv_4}.exe" - BrandingText "Jellyfin ${expv_1}.${expv_2}.${expv_3}.${expv_4} Installer" - VIProductVersion "${expv_1}.${expv_2}.${expv_3}.${expv_4}" - VIFileVersion "${expv_1}.${expv_2}.${expv_3}.${expv_4}" +; Align installer version with jellyfin.dll version + !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ + !echo "jellyfin.dll version is ${ver_1}.${ver_2}.${ver_3}.${ver_4}" ;!echo will print it while building + + Name "Jellyfin ${ver_1}.${ver_2}.${ver_3}.${ver_4}" + OutFile "Jellyfin.Installer.${ver_1}.${ver_2}.${ver_3}.${ver_4}.exe" + BrandingText "Jellyfin ${ver_1}.${ver_2}.${ver_3}.${ver_4} Installer" + +; installer attributes + VIProductVersion "${ver_1}.${ver_2}.${ver_3}.${ver_4}" + VIFileVersion "${ver_1}.${ver_2}.${ver_3}.${ver_4}" VIAddVersionKey "ProductName" "Jellyfin" - VIAddVersionKey "FileVersion" "${expv_1}.${expv_2}.${expv_3}.${expv_4}" + VIAddVersionKey "FileVersion" "${ver_1}.${ver_2}.${ver_3}.${ver_4}" ;Default installation folder InstallDir "$APPDATA\Jellyfin" @@ -35,19 +40,21 @@ ;-------------------------------- ;Pages -; !insertmacro MUI_PAGE_LICENSE "${NSISDIR}\Docs\Modern UI\License.txt" +;TODO +;find a license to displayed before installer is started +; !insertmacro MUI_PAGE_LICENSE " Date: Sat, 6 Jul 2019 18:02:00 +1000 Subject: [PATCH 06/15] Changed order to include install scripts in installer --- deployment/windows/build-jellyfin.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index 7b04c93103..9a6be81d02 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -125,12 +125,12 @@ if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){ Write-Verbose "Starting NSSM Install" Install-NSSM $InstallLocation $Architecture } +Copy-Item .\deployment\windows\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 +Copy-Item .\deployment\windows\install.bat $InstallLocation\install.bat if($MakeNSIS.IsPresent -or ($MakeNSIS -eq $true)){ Write-Verbose "Starting NSIS Package creation" Make-NSIS $InstallLocation } -Copy-Item .\deployment\windows\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 -Copy-Item .\deployment\windows\install.bat $InstallLocation\install.bat if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){ Compress-Archive -Path $InstallLocation -DestinationPath "$InstallLocation/jellyfin.zip" -Force } From cea6a2217ecf1aaa7e1cb59bc90c2867f68dda7a Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 6 Jul 2019 18:34:48 +1000 Subject: [PATCH 07/15] Correct Service handling & LocalAppData folder The service is now completely controlled by nssm as with the install-jellyfin.ps1 The LocalAppData had the global context, its now Corrected order of Mandatory and Optional components. --- deployment/windows/jellyfin.nsi | 39 +++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 6187cf9fdd..57008a6085 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -70,6 +70,8 @@ Section "Install Jellyfin (required)" InstallJellyfin SetOutPath "$INSTDIR" + SetShellVarContext current + StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" ; Pack all the files that were just compiled File /r $%InstallLocation%\* @@ -92,31 +94,27 @@ Section "Install Jellyfin (required)" InstallJellyfin SectionEnd -;TODO -; This section hasn't been tested completely -Section /o "Jellyfin Service" InstallService - ExecWait '"$INSTDIR"\nssm.exe install Jellyfin "$INSTDIR"\jellyfin.exe --datadir "$_JELLYFINDATADIR_"' $0 - DetailPrint "Jellyfin Service install, $0" - Sleep 3000 - ExecWait '"$INSTDIR"\nssm.exe set Jellyfin Start SERVICE_DELAYED_AUTO_START' $0 - DetailPrint "Jellyfin Service setting, $0" - StrCpy $_SERVICEINSTALLED_ "YES" -SectionEnd - Section "Jellyfin desktop shortcut" DesktopShortcut SetShellVarContext current DetailPrint "Creating desktop shortcut" CreateShortCut "$DESKTOP\Jellyfin.lnk" "$INSTDIR\jellyfin.exe" SectionEnd -;TODO -; This section hasn't been tested completely. +Section /o "Jellyfin Service" InstallService + ExecWait '"$INSTDIR\nssm.exe" install Jellyfin "$INSTDIR\jellyfin.exe" --datadir "$_JELLYFINDATADIR_"' $0 + DetailPrint "Jellyfin Service install, $0" + Sleep 3000 + ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START' $0 + DetailPrint "Jellyfin Service setting, $0" + StrCpy $_SERVICEINSTALLED_ "YES" +SectionEnd + Section /o "Start Jellyfin after installation" LaunchJellyfin ; either start the service or launch jellyfin standalone StrCmp $_SERVICEINSTALLED_ "YES" ServiceStart Standalone ServiceStart: - ExecWait 'C:\Windows\System32\sc.exe start Jellyfin' $0 + ExecWait '"$INSTDIR\nssm.exe" start Jellyfin' $0 DetailPrint "Jellyfin service start, $0" Return @@ -162,9 +160,14 @@ SectionEnd ;Uninstaller Section Section "Uninstall" + SetShellVarContext current + StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" ;TODO -; stop service or running instance -; Figure out a way to stop Jellyfin - either standalone or service when uninstaller is invoked +; stop running instance + ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0 + DetailPrint "Jellyfin service stop, $0" + ExecWait '"$INSTDIR\nssm.exe" remove Jellyfin confirm' $0 + DetailPrint "Jellyfin Service remove, $0" Delete "$INSTDIR\Uninstall.exe" RMDir /r "$INSTDIR" @@ -181,7 +184,9 @@ Function .onInit ; Align installer version with jellyfin.dll version !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" + SetShellVarContext current + StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" + DetailPrint "_JELLYFINDATADIR_ : $_JELLYFINDATADIR_" StrCpy $_SERVICEINSTALLED_ "NO" SectionSetFlags ${InstallJellyfin} 17 ; this makes the InstallJellyfin section mandatory FunctionEnd From 3d0e7f6cb6aac6622ad0df413c57b85d83679693 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sun, 7 Jul 2019 09:10:35 +1000 Subject: [PATCH 08/15] Include License file with installation --- deployment/windows/build-jellyfin.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index 9a6be81d02..b049c351a2 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -127,6 +127,7 @@ if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){ } Copy-Item .\deployment\windows\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1 Copy-Item .\deployment\windows\install.bat $InstallLocation\install.bat +Copy-Item .\LICENSE $InstallLocation\LICENSE if($MakeNSIS.IsPresent -or ($MakeNSIS -eq $true)){ Write-Verbose "Starting NSIS Package creation" Make-NSIS $InstallLocation From da71354e82276647c1e687ca677acc3b4e1c3a54 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sun, 7 Jul 2019 09:13:27 +1000 Subject: [PATCH 09/15] Remove Emby migration section, include License --- deployment/windows/jellyfin.nsi | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 57008a6085..98bf5d366d 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -6,7 +6,7 @@ !include "MUI2.nsh" Var _JELLYFINVERSION_ - Var _DEFAULTEMBYDATADIR_ +; Var _DEFAULTEMBYDATADIR_ Var _JELLYFINDATADIR_ Var _SERVICEINSTALLED_ ;-------------------------------- @@ -40,20 +40,20 @@ ;-------------------------------- ;Pages -;TODO -;find a license to displayed before installer is started -; !insertmacro MUI_PAGE_LICENSE " Date: Sun, 7 Jul 2019 09:17:03 +1000 Subject: [PATCH 10/15] Correct comment --- deployment/windows/jellyfin.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 98bf5d366d..d9a30a0fc5 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -32,7 +32,7 @@ ;Get installation folder from registry if available InstallDirRegKey HKLM "Software\Jellyfin" "InstallLocation" - ;Request application privileges for Windows Vista + ;Request application privileges for service installation RequestExecutionLevel admin CRCCheck on !define MUI_ABORTWARNING From aff72323c6d95e15efad88c4415bb33565e62ca2 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Tue, 9 Jul 2019 22:56:23 +1000 Subject: [PATCH 11/15] Update code for in-place upgrades --- deployment/windows/jellyfin.nsi | 99 +++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 10 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index d9a30a0fc5..6198f9c039 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -9,6 +9,8 @@ ; Var _DEFAULTEMBYDATADIR_ Var _JELLYFINDATADIR_ Var _SERVICEINSTALLED_ + Var _EXISTINGINSTALLATION_ + Var _EXISTINGSERVICE_ ;-------------------------------- ;General @@ -25,14 +27,16 @@ VIFileVersion "${ver_1}.${ver_2}.${ver_3}.${ver_4}" VIAddVersionKey "ProductName" "Jellyfin" VIAddVersionKey "FileVersion" "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - - ;Default installation folder + VIAddVersionKey "LegalCopyright" "Jellyfin, Free Software Media System" + VIAddVersionKey "FileDescription" "Jellyfin, Free Software Media System" + +;Default installation folder InstallDir "$APPDATA\Jellyfin" - ;Get installation folder from registry if available +;Get installation folder from registry if available InstallDirRegKey HKLM "Software\Jellyfin" "InstallLocation" - ;Request application privileges for service installation +;Request application privileges for service installation RequestExecutionLevel admin CRCCheck on !define MUI_ABORTWARNING @@ -42,6 +46,7 @@ !insertmacro MUI_PAGE_LICENSE "$%InstallLocation%\LICENSE" !insertmacro MUI_PAGE_COMPONENTS + !define MUI_PAGE_CUSTOMFUNCTION_PRE HideDirectoryPage !insertmacro MUI_PAGE_DIRECTORY ; Custom Directory page to ask for Emby Library location in case its needed @@ -69,6 +74,20 @@ ;Installer Sections Section "Install Jellyfin (required)" InstallJellyfin + StrCmp $_EXISTINGINSTALLATION_ "YES" CheckService CarryOn + + CheckService: + StrCmp $_EXISTINGSERVICE_ "YES" StopService ExistingInstallButNotService + + StopService: ; we stop the service to copy files in use + ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0 + DetailPrint "Jellyfin service stop, $0" + + ExistingInstallButNotService: +;TODO, find a way to kill the process in case it was started as standalone + MessageBox MB_OK|MB_ICONINFORMATION "Please stop Jellyfin manually before proceeding further." + + CarryOn: SetOutPath "$INSTDIR" SetShellVarContext current StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" @@ -94,7 +113,7 @@ Section "Install Jellyfin (required)" InstallJellyfin SectionEnd -Section "Jellyfin desktop shortcut" DesktopShortcut +Section /o "Jellyfin desktop shortcut" DesktopShortcut SetShellVarContext current DetailPrint "Creating desktop shortcut" CreateShortCut "$DESKTOP\Jellyfin.lnk" "$INSTDIR\jellyfin.exe" @@ -119,8 +138,9 @@ Section /o "Start Jellyfin after installation" LaunchJellyfin Return Standalone: - ExecWait '"$INSTDIR"\jellyfin.exe' $0 + ExecWait '"$INSTDIR\jellyfin.exe"' $0 DetailPrint "$INSTDIR\jellyfin.exe start, $0" + Return SectionEnd @@ -161,16 +181,26 @@ SectionEnd Section "Uninstall" SetShellVarContext current StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" -;TODO -; stop running instance + +; Currently we try to stop & remove a running service even if it doesn't exist +; not really sure about nssm statuscode detection method +; nothing to loose with brute force stop & remove method ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0 DetailPrint "Jellyfin service stop, $0" ExecWait '"$INSTDIR\nssm.exe" remove Jellyfin confirm' $0 DetailPrint "Jellyfin Service remove, $0" Delete "$INSTDIR\Uninstall.exe" - RMDir /r "$INSTDIR" - RMDir /r "$_JELLYFINDATADIR_" + +;TODO +; stop running instance gracefully, in case its running, the /REBOOTOK flag will delete it on reboot. + RMDir /r /REBOOTOK "$INSTDIR" ; + + MessageBox MB_YESNO|MB_ICONINFORMATION "Do you want to retain Jellyfin settings ? The media will not be touched in any case." /SD IDYES IDYES PreserveData + RMDir /r /REBOOTOK "$_JELLYFINDATADIR_" + + PreserveData: + DeleteRegKey HKLM "Software\Jellyfin" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" Delete "$DESKTOP\Jellyfin.lnk" @@ -179,6 +209,46 @@ SectionEnd Function .onInit + StrCpy $_EXISTINGINSTALLATION_ "NO" + StrCpy $_EXISTINGSERVICE_ "NO" +;Detect if Jellyfin is already installed. +; In case it is installed, let the user choose either +; 1. Exit installer +; 2. Upgrade without messing with data +; 2a. Don't ask for any installation folder +; 2b. If there is a service, don't ask for service installation or launch +; 2c. If no service, ask for autolaunch, and start as standalone + +; Read Registry for installation + ClearErrors + ReadRegStr "$0" HKLM "Software\Jellyfin" "InstallLocation" + IfErrors NoExisitingInstall + + DetailPrint "Existing Jellyfin detected at: $0" + StrCpy "$INSTDIR" "$0" + StrCpy $_EXISTINGINSTALLATION_ "YES" + SectionSetText ${InstallJellyfin} "Upgrade Jellyfin" ; Change install text to "Upgrade" + +; check if there is a service called Jellyfin +; hack : nssm statuscode Jellyfin will return non zero return code in case it exists + ExecWait '"$INSTDIR\nssm.exe" statuscode Jellyfin' $0 + DetailPrint "Jellyfin service statuscode, $0" + IntCmp $0 0 NoService ; service doesn't exist + + StrCpy $_EXISTINGSERVICE_ "YES" + SectionSetText ${InstallService} "" ; hide service install option if old install was a service + SectionSetText ${LaunchJellyfin} "" ; hide service start option if old install was a service + SectionSetText ${DesktopShortcut} "" ; hide desktop shortcut option too + + NoService: +; if detected, let the user know that we'll upgrade and its ok to quit + MessageBox MB_OKCANCEL|MB_ICONINFORMATION "Existing installation of Jellyfin was detected, it'll be upgraded, settings will be retained" /SD IDOK IDOK Proceed + Quit ; Quit if the user is not sure about upgrade + + Proceed: + + NoExisitingInstall: + SetShellVarContext all ; Align installer version with jellyfin.dll version !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ @@ -188,6 +258,15 @@ Function .onInit DetailPrint "_JELLYFINDATADIR_ : $_JELLYFINDATADIR_" StrCpy $_SERVICEINSTALLED_ "NO" SectionSetFlags ${InstallJellyfin} 17 ; this makes the InstallJellyfin section mandatory + +FunctionEnd + +Function HideDirectoryPage + StrCmp $_EXISTINGINSTALLATION_ "NO" show + + Abort ; Dont show folder selection if just upgrading + + show: FunctionEnd ; This can be uncommented in case Emby Migration is planned later From e31851d25ee08f648bc9a31a6cea8cc2e67ce6cd Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 13 Jul 2019 21:16:56 +1000 Subject: [PATCH 12/15] Update to uninstall silently if already installed --- deployment/windows/jellyfin.nsi | 95 ++++++++++++--------------------- 1 file changed, 33 insertions(+), 62 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 6198f9c039..3a11bf1d83 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -2,15 +2,15 @@ ; This can be removed once stable. !verbose 4 ;-------------------------------- -;Include Modern UI !include "MUI2.nsh" + Var _JELLYFINVERSION_ -; Var _DEFAULTEMBYDATADIR_ Var _JELLYFINDATADIR_ Var _SERVICEINSTALLED_ Var _EXISTINGINSTALLATION_ Var _EXISTINGSERVICE_ + ;-------------------------------- ;General @@ -47,21 +47,9 @@ !insertmacro MUI_PAGE_LICENSE "$%InstallLocation%\LICENSE" !insertmacro MUI_PAGE_COMPONENTS !define MUI_PAGE_CUSTOMFUNCTION_PRE HideDirectoryPage - !insertmacro MUI_PAGE_DIRECTORY - -; Custom Directory page to ask for Emby Library location in case its needed -; Commented for now to avoid showing this. -; This can be uncommented in case Emby Migration is planned later -; !define MUI_PAGE_HEADER_TEXT "Emby Library locaton" -; !define MUI_PAGE_HEADER_SUBTEXT "" -; !define MUI_DIRECTORYPAGE_TEXT_TOP "Please select the folder where Emby library is present. This will have Enby folders like config, cache, data, metadata, etc." -; !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Emby Library location" -; !define MUI_PAGE_CUSTOMFUNCTION_PRE ShowEmbyLibraryPage -; !define MUI_DIRECTORYPAGE_VARIABLE $_DEFAULTEMBYDATADIR_ -; !insertmacro MUI_PAGE_DIRECTORY - + !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES - + !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES @@ -74,25 +62,29 @@ ;Installer Sections Section "Install Jellyfin (required)" InstallJellyfin - StrCmp $_EXISTINGINSTALLATION_ "YES" CheckService CarryOn - - CheckService: - StrCmp $_EXISTINGSERVICE_ "YES" StopService ExistingInstallButNotService - - StopService: ; we stop the service to copy files in use - ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0 - DetailPrint "Jellyfin service stop, $0" - - ExistingInstallButNotService: -;TODO, find a way to kill the process in case it was started as standalone - MessageBox MB_OK|MB_ICONINFORMATION "Please stop Jellyfin manually before proceeding further." +; If previous installation is present, run the uninstaller silently + StrCmp "$_EXISTINGINSTALLATION_" "YES" RunUninstaller CarryOn + RunUninstaller: + DetailPrint "Looking for uninstaller at $INSTDIR" + FindFirst $0 $1 "$INSTDIR\Uninstall.exe" + FindClose $0 + StrCmp $1 "" CarryOn ; the registry key was there but uninstaller was not found + + DetailPrint "Silently running the uninstaller at $INSTDIR" + ExecWait '"$INSTDIR\Uninstall.exe" /S _?=$INSTDIR' $0 + DetailPrint "Uninstall finished, $0" + Delete "$INSTDIR\Uninstall.exe" + CarryOn: + SetOutPath "$INSTDIR" - SetShellVarContext current + + SetShellVarContext current ; Local App Data folder for current user only StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" ; Pack all the files that were just compiled +; These will be exploded to $INSTDIR File /r $%InstallLocation%\* ; Write the installation path into the registry @@ -114,12 +106,12 @@ Section "Install Jellyfin (required)" InstallJellyfin SectionEnd Section /o "Jellyfin desktop shortcut" DesktopShortcut - SetShellVarContext current + SetShellVarContext current ; to create the shortcut for current user only DetailPrint "Creating desktop shortcut" CreateShortCut "$DESKTOP\Jellyfin.lnk" "$INSTDIR\jellyfin.exe" SectionEnd -Section /o "Jellyfin Service" InstallService +Section "Jellyfin Service" InstallService ExecWait '"$INSTDIR\nssm.exe" install Jellyfin "$INSTDIR\jellyfin.exe" --datadir "$_JELLYFINDATADIR_"' $0 DetailPrint "Jellyfin Service install, $0" Sleep 3000 @@ -128,7 +120,7 @@ Section /o "Jellyfin Service" InstallService StrCpy $_SERVICEINSTALLED_ "YES" SectionEnd -Section /o "Start Jellyfin after installation" LaunchJellyfin +Section "Start Jellyfin after installation" LaunchJellyfin ; either start the service or launch jellyfin standalone StrCmp $_SERVICEINSTALLED_ "YES" ServiceStart Standalone @@ -144,35 +136,21 @@ Section /o "Start Jellyfin after installation" LaunchJellyfin SectionEnd -; This can be uncommented in case Emby Migration is planned later -;Section /o "Migrate Emby Library" MigrateEmbyLibrary -; DetailPrint "Migrating Emby Library" -; CopyFiles $_DEFAULTEMBYDATADIR_/config $_JELLYFINDATADIR_ -; CopyFiles $_DEFAULTEMBYDATADIR_/cache $_JELLYFINDATADIR_ -; CopyFiles $_DEFAULTEMBYDATADIR_/data $_JELLYFINDATADIR_ -; CopyFiles $_DEFAULTEMBYDATADIR_/metadata $_JELLYFINDATADIR_ -; CopyFiles $_DEFAULTEMBYDATADIR_/root $_JELLYFINDATADIR_ - -;SectionEnd - - ;-------------------------------- ;Descriptions - ;Language strings +;Language strings LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin" LangString DESC_InstallService ${LANG_ENGLISH} "Install As a Service" LangString DESC_DesktopShortcut ${LANG_ENGLISH} "Create a desktop shortcut" LangString DESC_LaunchJellyfin ${LANG_ENGLISH} "Start Jellyfin after Install" -; LangString DESC_MigrateEmbyLibrary ${LANG_ENGLISH} "Migrate existing Emby Library" - ;Assign language strings to sections +;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${InstallJellyfin} $(DESC_InstallJellyfin) !insertmacro MUI_DESCRIPTION_TEXT ${DesktopShortcut} $(DESC_DesktopShortcut) !insertmacro MUI_DESCRIPTION_TEXT ${InstallService} $(DESC_InstallService) !insertmacro MUI_DESCRIPTION_TEXT ${LaunchJellyfin} $(DESC_LaunchJellyfin) -; !insertmacro MUI_DESCRIPTION_TEXT ${MigrateEmbyLibrary} $(DESC_MigrateEmbyLibrary) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- @@ -208,7 +186,9 @@ Section "Uninstall" SectionEnd + Function .onInit + StrCpy $_EXISTINGINSTALLATION_ "NO" StrCpy $_EXISTINGSERVICE_ "NO" ;Detect if Jellyfin is already installed. @@ -228,7 +208,7 @@ Function .onInit StrCpy "$INSTDIR" "$0" StrCpy $_EXISTINGINSTALLATION_ "YES" SectionSetText ${InstallJellyfin} "Upgrade Jellyfin" ; Change install text to "Upgrade" - + ; check if there is a service called Jellyfin ; hack : nssm statuscode Jellyfin will return non zero return code in case it exists ExecWait '"$INSTDIR\nssm.exe" statuscode Jellyfin' $0 @@ -246,13 +226,15 @@ Function .onInit Quit ; Quit if the user is not sure about upgrade Proceed: - + NoExisitingInstall: SetShellVarContext all + ; Align installer version with jellyfin.dll version !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}.${ver_4}" + SetShellVarContext current StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" DetailPrint "_JELLYFINDATADIR_ : $_JELLYFINDATADIR_" @@ -264,18 +246,7 @@ FunctionEnd Function HideDirectoryPage StrCmp $_EXISTINGINSTALLATION_ "NO" show - Abort ; Dont show folder selection if just upgrading + Abort ; Don't show folder selection if just upgrading show: FunctionEnd - -; This can be uncommented in case Emby Migration is planned later -;Function ShowEmbyLibraryPage -; SectionGetFlags ${MigrateEmbyLibrary} $R0 -; IntOp $R0 $R0 & ${SF_SELECTED} -; IntCmp $R0 ${SF_SELECTED} show - -; Abort ; Dont show the Emby folder selection window if Emby migrartion is not selected - -; show: -;FunctionEnd From fbbcba95d3712b0f7f61e5c2026914bf42f2b59b Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Thu, 25 Jul 2019 21:51:53 +1000 Subject: [PATCH 13/15] Update installer name to copy --- deployment/windows/build-jellyfin.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/windows/build-jellyfin.ps1 index b049c351a2..aaa4bcf6c4 100644 --- a/deployment/windows/build-jellyfin.ps1 +++ b/deployment/windows/build-jellyfin.ps1 @@ -108,7 +108,7 @@ function Make-NSIS { Expand-Archive "$tempdir/nsis.zip" -DestinationPath "$tempdir/nsis/" -Force | Write-Verbose $env:InstallLocation = $InstallLocation & "$tempdir/nsis/nsis-3.04/makensis.exe" ".\deployment\windows\jellyfin.nsi" - Copy-Item .\deployment\windows\Jellyfin.Installer.*.exe $InstallLocation\..\ + Copy-Item .\deployment\windows\jellyfin_*.exe $InstallLocation\..\ Remove-Item "$tempdir/nsis/" -Recurse -Force -ErrorAction Continue | Write-Verbose Remove-Item "$tempdir/nsis.zip" -Force -ErrorAction Continue | Write-Verbose From 5517d912bfb1d77388805d4d759e875541589265 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Thu, 25 Jul 2019 21:52:44 +1000 Subject: [PATCH 14/15] Rework based on review comments --- deployment/windows/jellyfin.nsi | 389 +++++++++++++++++++++----------- 1 file changed, 259 insertions(+), 130 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 3a11bf1d83..5e3dcac841 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -2,68 +2,113 @@ ; This can be removed once stable. !verbose 4 ;-------------------------------- +!define SF_USELECTED 0 ; used to check selected options status, rest are inherited from Sections.nsh !include "MUI2.nsh" - + !include "Sections.nsh" + !include "LogicLib.nsh" + +; Global variables that we'll use Var _JELLYFINVERSION_ Var _JELLYFINDATADIR_ - Var _SERVICEINSTALLED_ + Var _INSTALLSERVICE_ + Var _SERVICESTART_ + Var _NETWORKSERVICEACCOUNT_ Var _EXISTINGINSTALLATION_ Var _EXISTINGSERVICE_ + Var _CUSTOMDATAFOLDER_ + +!if ${NSIS_PTR_SIZE} > 4 + !define BITS 64 + !define NAMESUFFIX " (64 bit)" +!else + !define BITS 32 + !define NAMESUFFIX "" +!endif ;-------------------------------- -;General -; Align installer version with jellyfin.dll version - !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ - !echo "jellyfin.dll version is ${ver_1}.${ver_2}.${ver_3}.${ver_4}" ;!echo will print it while building - - Name "Jellyfin ${ver_1}.${ver_2}.${ver_3}.${ver_4}" - OutFile "Jellyfin.Installer.${ver_1}.${ver_2}.${ver_3}.${ver_4}.exe" - BrandingText "Jellyfin ${ver_1}.${ver_2}.${ver_3}.${ver_4} Installer" - -; installer attributes - VIProductVersion "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - VIFileVersion "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - VIAddVersionKey "ProductName" "Jellyfin" - VIAddVersionKey "FileVersion" "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - VIAddVersionKey "LegalCopyright" "Jellyfin, Free Software Media System" - VIAddVersionKey "FileDescription" "Jellyfin, Free Software Media System" + !define REG_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" ;Registry to show up in Add/Remove Programs -;Default installation folder - InstallDir "$APPDATA\Jellyfin" + !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ ;Align installer version with jellyfin.dll version + Name "Jellyfin Server ${ver_1}.${ver_2}.${ver_3}" ; This is referred in various header text labels + OutFile "jellyfin_${ver_1}.${ver_2}.${ver_3}_windows.exe" ; Naming convention jellyfin_{version}_windows-{arch].exe + BrandingText "Jellyfin Server ${ver_1}.${ver_2}.${ver_3} Installer" ; This shows in just over the buttons + +; installer attributes, these show up in details tab on installer properties + VIProductVersion "${ver_1}.${ver_2}.${ver_3}.0" ; VIProductVersion format, should be X.X.X.X + VIFileVersion "${ver_1}.${ver_2}.${ver_3}.0" ; VIFileVersion format, should be X.X.X.X + VIAddVersionKey "ProductName" "Jellyfin Server" + VIAddVersionKey "FileVersion" "${ver_1}.${ver_2}.${ver_3}.0" + VIAddVersionKey "LegalCopyright" "Jellyfin, Free Software Media System" + VIAddVersionKey "FileDescription" "Jellyfin Server" + +;TODO, check defaults + InstallDir "$PROGRAMFILES\Jellyfin" ;Default installation folder + InstallDirRegKey HKLM "Software\Jellyfin" "InstallFolder" ;Read the registry for install folder, -;Get installation folder from registry if available - InstallDirRegKey HKLM "Software\Jellyfin" "InstallLocation" - -;Request application privileges for service installation - RequestExecutionLevel admin - CRCCheck on - !define MUI_ABORTWARNING + RequestExecutionLevel admin ; ask it upfront for service control, and installing in priv folders + + CRCCheck on ; make sure the installer wasn't corrupted while downloading + + !define MUI_ABORTWARNING ;Prompts user in case of aborting install + +; TODO: Replace with nice Jellyfin Icons + !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-install.ico" ; Installer Icon + !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico" ; Uninstaller Icon + + !define MUI_HEADERIMAGE + !define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\nsis3-branding.bmp" + !define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\nsis3-branding.bmp" ;-------------------------------- ;Pages - !insertmacro MUI_PAGE_LICENSE "$%InstallLocation%\LICENSE" +; Welcome Page + !define MUI_WELCOMEPAGE_TEXT "The installer will ask for details to install Jellyfin Server.$\r$\n$\r$\n$\r$\n\ + ADVANCED:$\r$\n\ + The default service install uses Local System account and is sufficient for most users. $\r$\n$\r$\n\ + You can choose to install using Network Service 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\ + You can choose the folder for Jellyfin Metadata under advanced options based on your needs." + !insertmacro MUI_PAGE_WELCOME +; License Page + !insertmacro MUI_PAGE_LICENSE "$%InstallLocation%\LICENSE" ; picking up generic GPL +; Components Page + !define MUI_COMPONENTSPAGE_SMALLDESC !insertmacro MUI_PAGE_COMPONENTS - !define MUI_PAGE_CUSTOMFUNCTION_PRE HideDirectoryPage - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - + !define MUI_PAGE_CUSTOMFUNCTION_PRE HideInstallDirectoryPage ; Controls when to hide / show + !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Install folder" ; shows just above the folder selection dialog + !insertmacro MUI_PAGE_DIRECTORY + +; Metadata folder Page + !define MUI_PAGE_CUSTOMFUNCTION_PRE HideDataDirectoryPage ; Controls when to hide / show + !define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install the Jellyfin Server metadata." + !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." + !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Metadata folder" + !define MUI_DIRECTORYPAGE_VARIABLE $_JELLYFINDATADIR_ + !insertmacro MUI_PAGE_DIRECTORY + +; Confirmation Page + Page custom ConfirmationPage ; just letting the user know what they chose to install + +; Actual Installion Page + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES + !insertmacro MUI_UNPAGE_FINISH ;-------------------------------- -;Languages - +;Languages; Add more languages later here if needed !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Installer Sections - -Section "Install Jellyfin (required)" InstallJellyfin -; If previous installation is present, run the uninstaller silently - StrCmp "$_EXISTINGINSTALLATION_" "YES" RunUninstaller CarryOn +Section "Jellyfin Server (required)" InstallJellyfin + SectionIn RO ; Mandatory section, isn't this the whole purpose to run the installer. + + StrCmp "$_EXISTINGINSTALLATION_" "YES" RunUninstaller CarryOn ; Silently uninstall in case of previous installation RunUninstaller: DetailPrint "Looking for uninstaller at $INSTDIR" @@ -74,179 +119,263 @@ Section "Install Jellyfin (required)" InstallJellyfin DetailPrint "Silently running the uninstaller at $INSTDIR" ExecWait '"$INSTDIR\Uninstall.exe" /S _?=$INSTDIR' $0 DetailPrint "Uninstall finished, $0" - Delete "$INSTDIR\Uninstall.exe" CarryOn: SetOutPath "$INSTDIR" - - SetShellVarContext current ; Local App Data folder for current user only - StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" -; Pack all the files that were just compiled -; These will be exploded to $INSTDIR File /r $%InstallLocation%\* -; Write the installation path into the registry - WriteRegStr HKLM "Software\Jellyfin" "InstallLocation" "$INSTDIR" +; Write the InstallFolder, DataFolder, Network Service info into the registry for later use + WriteRegExpandStr HKLM "Software\Jellyfin" "InstallFolder" "$INSTDIR" + WriteRegExpandStr HKLM "Software\Jellyfin" "DataFolder" "$_JELLYFINDATADIR_" + WriteRegStr HKLM "Software\Jellyfin" "NetworkService" "$_NETWORKSERVICEACCOUNT_" + + !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ + StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}" ; ; Write the uninstall keys for Windows - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayName" "Jellyfin $_JELLYFINVERSION_" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "UninstallString" '"$INSTDIR\Uninstall.exe"' - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayIcon" '"$INSTDIR\Jellyfin.exe",0' - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "Publisher" "The Jellyfin project" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "URLInfoAbout" "https://jellyfin.github.io/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "DisplayVersion" "$_JELLYFINVERSION_" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" "NoRepair" 1 + WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayName" "Jellyfin $_JELLYFINVERSION_" + WriteRegExpandStr HKLM "${REG_UNINST_KEY}" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayIcon" '"$INSTDIR\Jellyfin.exe",0' + WriteRegStr HKLM "${REG_UNINST_KEY}" "Publisher" "The Jellyfin project" + WriteRegStr HKLM "${REG_UNINST_KEY}" "URLInfoAbout" "https://jellyfin.github.io/" + WriteRegStr HKLM "${REG_UNINST_KEY}" "DisplayVersion" "$_JELLYFINVERSION_" + WriteRegDWORD HKLM "${REG_UNINST_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${REG_UNINST_KEY}" "NoRepair" 1 ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd -Section /o "Jellyfin desktop shortcut" DesktopShortcut - SetShellVarContext current ; to create the shortcut for current user only - DetailPrint "Creating desktop shortcut" - CreateShortCut "$DESKTOP\Jellyfin.lnk" "$INSTDIR\jellyfin.exe" -SectionEnd - Section "Jellyfin Service" InstallService + ExecWait '"$INSTDIR\nssm.exe" install Jellyfin "$INSTDIR\jellyfin.exe" --datadir "$_JELLYFINDATADIR_"' $0 DetailPrint "Jellyfin Service install, $0" - Sleep 3000 + + Sleep 3000 ; Give time for Windows to catchup + ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START' $0 DetailPrint "Jellyfin Service setting, $0" - StrCpy $_SERVICEINSTALLED_ "YES" + + Sleep 3000 + ${If} $_NETWORKSERVICEACCOUNT_ == "YES" + DetailPrint "Attempting to change service account to Network Service" + ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Objectname "Network Service"' $0 + DetailPrint "Jellyfin service account change, $0" + ${EndIf} + SectionEnd -Section "Start Jellyfin after installation" LaunchJellyfin -; either start the service or launch jellyfin standalone - StrCmp $_SERVICEINSTALLED_ "YES" ServiceStart Standalone - - ServiceStart: +Section "Start Jellyfin service after install" StartService + ExecWait '"$INSTDIR\nssm.exe" start Jellyfin' $0 DetailPrint "Jellyfin service start, $0" - Return - Standalone: - ExecWait '"$INSTDIR\jellyfin.exe"' $0 - DetailPrint "$INSTDIR\jellyfin.exe start, $0" - Return - SectionEnd +SectionGroup "Advanced" +Section /o "Use Network Service account" NetworkServiceAccount + ; The section is for user choice, nothing to do here +SectionEnd +Section /o "Custom Jellyfin metadata folder" CustomDataFolder + ; The section is for user choice, nothing to do here +SectionEnd +SectionGroupEnd + + ;-------------------------------- ;Descriptions ;Language strings - LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin" + LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin Server" LangString DESC_InstallService ${LANG_ENGLISH} "Install As a Service" - LangString DESC_DesktopShortcut ${LANG_ENGLISH} "Create a desktop shortcut" - LangString DESC_LaunchJellyfin ${LANG_ENGLISH} "Start Jellyfin after Install" + LangString DESC_StartService ${LANG_ENGLISH} "Start Jellyfin service after Install" + LangString DESC_NetworkServiceAccount ${LANG_ENGLISH} "Use Network Service account to start windows service" + LangString DESC_CustomDataFolder ${LANG_ENGLISH} "Choose Jellyfin Server metadata folder in subsequent steps" ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${InstallJellyfin} $(DESC_InstallJellyfin) - !insertmacro MUI_DESCRIPTION_TEXT ${DesktopShortcut} $(DESC_DesktopShortcut) !insertmacro MUI_DESCRIPTION_TEXT ${InstallService} $(DESC_InstallService) - !insertmacro MUI_DESCRIPTION_TEXT ${LaunchJellyfin} $(DESC_LaunchJellyfin) + !insertmacro MUI_DESCRIPTION_TEXT ${StartService} $(DESC_StartService) + !insertmacro MUI_DESCRIPTION_TEXT ${NetworkServiceAccount} $(DESC_NetworkServiceAccount) + !insertmacro MUI_DESCRIPTION_TEXT ${CustomDataFolder} $(DESC_CustomDataFolder) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Uninstaller Section Section "Uninstall" - SetShellVarContext current - StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" + + ReadRegStr $INSTDIR HKLM "Software\Jellyfin" "InstallFolder" ; read the installation folder + ReadRegStr $_JELLYFINDATADIR_ HKLM "Software\Jellyfin" "DataFolder" ; read the metadata folder + + DetailPrint "Jellyfin Install location : $INSTDIR" + DetailPrint "Jellyfin data folder : $_JELLYFINDATADIR_" -; Currently we try to stop & remove a running service even if it doesn't exist -; not really sure about nssm statuscode detection method -; nothing to loose with brute force stop & remove method + 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 + + RMDir /r /REBOOTOK "$_JELLYFINDATADIR_" + + PreserveData: + + DetailPrint "Attempting to stop Jellyfin Server" ExecWait '"$INSTDIR\nssm.exe" stop Jellyfin' $0 DetailPrint "Jellyfin service stop, $0" + DetailPrint "Attempting to remove Jellyfin service" ExecWait '"$INSTDIR\nssm.exe" remove Jellyfin confirm' $0 DetailPrint "Jellyfin Service remove, $0" Delete "$INSTDIR\Uninstall.exe" -;TODO -; stop running instance gracefully, in case its running, the /REBOOTOK flag will delete it on reboot. - RMDir /r /REBOOTOK "$INSTDIR" ; - - MessageBox MB_YESNO|MB_ICONINFORMATION "Do you want to retain Jellyfin settings ? The media will not be touched in any case." /SD IDYES IDYES PreserveData - RMDir /r /REBOOTOK "$_JELLYFINDATADIR_" - - PreserveData: + RMDir /r /REBOOTOK "$INSTDIR" DeleteRegKey HKLM "Software\Jellyfin" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Jellyfin" - Delete "$DESKTOP\Jellyfin.lnk" + DeleteRegKey HKLM "${REG_UNINST_KEY}" SectionEnd Function .onInit - +; Setting up defaults + StrCpy $_INSTALLSERVICE_ "YES" + StrCpy $_SERVICESTART_ "YES" + StrCpy $_CUSTOMDATAFOLDER_ "NO" + StrCpy $_NETWORKSERVICEACCOUNT_ "NO" StrCpy $_EXISTINGINSTALLATION_ "NO" StrCpy $_EXISTINGSERVICE_ "NO" + + SetShellVarContext current + StrCpy $_JELLYFINDATADIR_ "$%ProgramData%\jellyfin\" + ;Detect if Jellyfin is already installed. ; In case it is installed, let the user choose either ; 1. Exit installer ; 2. Upgrade without messing with data -; 2a. Don't ask for any installation folder -; 2b. If there is a service, don't ask for service installation or launch -; 2c. If no service, ask for autolaunch, and start as standalone +; 2a. Don't ask for any details, uninstall and install afresh with old settings -; Read Registry for installation +; Read Registry for previous installation ClearErrors - ReadRegStr "$0" HKLM "Software\Jellyfin" "InstallLocation" + ReadRegStr "$0" HKLM "Software\Jellyfin" "InstallFolder" IfErrors NoExisitingInstall DetailPrint "Existing Jellyfin detected at: $0" - StrCpy "$INSTDIR" "$0" - StrCpy $_EXISTINGINSTALLATION_ "YES" - SectionSetText ${InstallJellyfin} "Upgrade Jellyfin" ; Change install text to "Upgrade" + StrCpy "$INSTDIR" "$0" ; set the location fro registry as new default + + StrCpy $_EXISTINGINSTALLATION_ "YES" ; Set our flag to be used later + SectionSetText ${InstallJellyfin} "Upgrade Jellyfin Server(required)" ; Change install text to "Upgrade" -; check if there is a service called Jellyfin +; check if there is a service called Jellyfin, there should be ; hack : nssm statuscode Jellyfin will return non zero return code in case it exists ExecWait '"$INSTDIR\nssm.exe" statuscode Jellyfin' $0 DetailPrint "Jellyfin service statuscode, $0" - IntCmp $0 0 NoService ; service doesn't exist - + IntCmp $0 0 NoService ; service doesn't exist, may be run from desktop shortcut + + ; if service was detected, set defaults going forward. StrCpy $_EXISTINGSERVICE_ "YES" - SectionSetText ${InstallService} "" ; hide service install option if old install was a service - SectionSetText ${LaunchJellyfin} "" ; hide service start option if old install was a service - SectionSetText ${DesktopShortcut} "" ; hide desktop shortcut option too + StrCpy $_INSTALLSERVICE_ "YES" + StrCpy $_SERVICESTART_ "YES" + + ; check if service was run using Network Service account + ClearErrors + ReadRegStr "$_NETWORKSERVICEACCOUNT_" HKLM "Software\Jellyfin" "NetworkService" ; in case of error _NETWORKSERVICEACCOUNT_ will be NO as default + + ClearErrors + ReadRegStr $_JELLYFINDATADIR_ HKLM "Software\Jellyfin" "DataFolder" ; in case of error, the default holds + + ; Hide sections which will not be needed in case of previous install + SectionSetText ${InstallService} "" + SectionSetText ${StartService} "" + SectionSetText ${NetworkServiceAccount} "" + SectionSetText ${CustomDataFolder} "" - NoService: -; if detected, let the user know that we'll upgrade and its ok to quit - MessageBox MB_OKCANCEL|MB_ICONINFORMATION "Existing installation of Jellyfin was detected, it'll be upgraded, settings will be retained" /SD IDOK IDOK Proceed + NoService: ; existing install was present but no service was detected + +; Let the user know that we'll upgrade and provide an option to quit. + MessageBox MB_OKCANCEL|MB_ICONINFORMATION "Existing installation of Jellyfin was detected, it'll be upgraded, settings will be retained. \ + $\r$\nClick OK to proceed, Cancel to exit installer." /SD IDOK IDOK ProceedWithUpgrade Quit ; Quit if the user is not sure about upgrade - Proceed: + ProceedWithUpgrade: NoExisitingInstall: - - SetShellVarContext all +; by this time, the variables have been correctly set to reflect previous install details -; Align installer version with jellyfin.dll version - !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ - StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}.${ver_4}" - - SetShellVarContext current - StrCpy $_JELLYFINDATADIR_ "$LOCALAPPDATA\jellyfin\" - DetailPrint "_JELLYFINDATADIR_ : $_JELLYFINDATADIR_" - StrCpy $_SERVICEINSTALLED_ "NO" - SectionSetFlags ${InstallJellyfin} 17 ; this makes the InstallJellyfin section mandatory - FunctionEnd -Function HideDirectoryPage - StrCmp $_EXISTINGINSTALLATION_ "NO" show - - Abort ; Don't show folder selection if just upgrading - - show: +Function HideInstallDirectoryPage + ${If} $_EXISTINGINSTALLATION_ == "YES" ; Existing installation detected, so don't ask for InstallFolder + Abort + ${EndIf} +FunctionEnd + +; Don't show custom folder option in case it wasn't chosen +Function HideDataDirectoryPage + ${If} $_CUSTOMDATAFOLDER_ == "NO" + Abort + ${EndIf} +FunctionEnd + +; This function handles the choices during component selection +Function .onSelChange + SectionGetFlags ${CustomDataFolder} $0 + ${If} $0 = ${SF_SELECTED} + StrCpy $_CUSTOMDATAFOLDER_ "YES" + ${Else} + StrCpy $_CUSTOMDATAFOLDER_ "NO" + ${EndIf} + +; If we are not installing service, we don't need to set the NetworkService account or StartService + SectionGetFlags ${InstallService} $0 + ${If} $0 = ${SF_SELECTED} + StrCpy $_INSTALLSERVICE_ "YES" + SectionGetFlags ${NetworkServiceAccount} $0 + IntOp $0 $0 | ${SF_RO} + IntOp $0 $0 ^ ${SF_RO} + SectionSetFlags ${NetworkServiceAccount} $0 + SectionGetFlags ${StartService} $0 + IntOp $0 $0 | ${SF_RO} + IntOp $0 $0 ^ ${SF_RO} + SectionSetFlags ${StartService} $0 + ${Else} + StrCpy $_INSTALLSERVICE_ "NO" + IntOp $0 ${SF_USELECTED} | ${SF_RO} + SectionSetFlags ${NetworkServiceAccount} $0 + SectionSetFlags ${StartService} $0 + ${EndIf} + + SectionGetFlags ${StartService} $0 + ${If} $0 = ${SF_SELECTED} + StrCpy $_SERVICESTART_ "YES" + ${Else} + StrCpy $_SERVICESTART_ "NO" + ${EndIf} + + SectionGetFlags ${NetworkServiceAccount} $0 + ${If} $0 = ${SF_SELECTED} + StrCpy $_NETWORKSERVICEACCOUNT_ "YES" + ${Else} + StrCpy $_NETWORKSERVICEACCOUNT_ "NO" + ${EndIf} + + +FunctionEnd + +Function ConfirmationPage + !insertmacro MUI_HEADER_TEXT "Confirmation Page" "Please confirm your choices for Jellyfin Server installation" + + nsDialogs::Create 1018 + + ${NSD_CreateLabel} 0 0 100% 100% "The installer will proceed based on the following inputs gathered on earlier screens.$\r$\n$\r$\n\ + Installation Folder : $INSTDIR$\r$\n\ + Service install : $_INSTALLSERVICE_$\r$\n\ + Service start : $_SERVICESTART_$\r$\n\ + Network Service Account : $_NETWORKSERVICEACCOUNT_$\r$\n\ + Custom Metadata folder : $_CUSTOMDATAFOLDER_$\r$\n\ + Jellyfin Metadata Folder: $_JELLYFINDATADIR_" + nsDialogs::Show + FunctionEnd From c6111a7fb57a7d919ebf453ff3b9248cb8c3f6f0 Mon Sep 17 00:00:00 2001 From: crankdoofus <52436708+crankdoofus@users.noreply.github.com> Date: Sat, 27 Jul 2019 20:23:22 +1000 Subject: [PATCH 15/15] Change service install user The default is Network Service, with advanced option to use Local System --- deployment/windows/jellyfin.nsi | 47 ++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/deployment/windows/jellyfin.nsi b/deployment/windows/jellyfin.nsi index 5e3dcac841..a374ebe45e 100644 --- a/deployment/windows/jellyfin.nsi +++ b/deployment/windows/jellyfin.nsi @@ -13,7 +13,7 @@ Var _JELLYFINDATADIR_ Var _INSTALLSERVICE_ Var _SERVICESTART_ - Var _NETWORKSERVICEACCOUNT_ + Var _LOCALSYSTEMACCOUNT_ Var _EXISTINGINSTALLATION_ Var _EXISTINGSERVICE_ Var _CUSTOMDATAFOLDER_ @@ -67,8 +67,8 @@ ; Welcome Page !define MUI_WELCOMEPAGE_TEXT "The installer will ask for details to install Jellyfin Server.$\r$\n$\r$\n$\r$\n\ ADVANCED:$\r$\n\ - The default service install uses Local System account and is sufficient for most users. $\r$\n$\r$\n\ - You can choose to install using Network Service 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\ + The default service install uses Network Service account and is sufficient for most users. $\r$\n$\r$\n\ + 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\ You can choose the folder for Jellyfin Metadata under advanced options based on your needs." !insertmacro MUI_PAGE_WELCOME ; License Page @@ -94,7 +94,6 @@ ; Actual Installion Page !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH @@ -129,7 +128,7 @@ Section "Jellyfin Server (required)" InstallJellyfin ; Write the InstallFolder, DataFolder, Network Service info into the registry for later use WriteRegExpandStr HKLM "Software\Jellyfin" "InstallFolder" "$INSTDIR" WriteRegExpandStr HKLM "Software\Jellyfin" "DataFolder" "$_JELLYFINDATADIR_" - WriteRegStr HKLM "Software\Jellyfin" "NetworkService" "$_NETWORKSERVICEACCOUNT_" + WriteRegStr HKLM "Software\Jellyfin" "LocalSystemAccount" "$_LOCALSYSTEMACCOUNT_" !getdllversion "$%InstallLocation%\jellyfin.dll" ver_ StrCpy $_JELLYFINVERSION_ "${ver_1}.${ver_2}.${ver_3}" ; @@ -160,10 +159,10 @@ Section "Jellyfin Service" InstallService DetailPrint "Jellyfin Service setting, $0" Sleep 3000 - ${If} $_NETWORKSERVICEACCOUNT_ == "YES" + ${If} $_LOCALSYSTEMACCOUNT_ == "NO" ; the default install using NSSM is Local System DetailPrint "Attempting to change service account to Network Service" ExecWait '"$INSTDIR\nssm.exe" set Jellyfin Objectname "Network Service"' $0 - DetailPrint "Jellyfin service account change, $0" + DetailPrint "Jellyfin service account change, $0" ${EndIf} SectionEnd @@ -175,8 +174,8 @@ Section "Start Jellyfin service after install" StartService SectionEnd -SectionGroup "Advanced" -Section /o "Use Network Service account" NetworkServiceAccount +SectionGroup "Advanced" Advanced +Section /o "Use Local System account" LocalSystemAccount ; The section is for user choice, nothing to do here SectionEnd Section /o "Custom Jellyfin metadata folder" CustomDataFolder @@ -192,7 +191,7 @@ SectionGroupEnd LangString DESC_InstallJellyfin ${LANG_ENGLISH} "Install Jellyfin Server" LangString DESC_InstallService ${LANG_ENGLISH} "Install As a Service" LangString DESC_StartService ${LANG_ENGLISH} "Start Jellyfin service after Install" - LangString DESC_NetworkServiceAccount ${LANG_ENGLISH} "Use Network Service account to start windows service" + LangString DESC_LocalSystemAccount ${LANG_ENGLISH} "Use Local System account to start windows service" LangString DESC_CustomDataFolder ${LANG_ENGLISH} "Choose Jellyfin Server metadata folder in subsequent steps" ;Assign language strings to sections @@ -200,7 +199,7 @@ SectionGroupEnd !insertmacro MUI_DESCRIPTION_TEXT ${InstallJellyfin} $(DESC_InstallJellyfin) !insertmacro MUI_DESCRIPTION_TEXT ${InstallService} $(DESC_InstallService) !insertmacro MUI_DESCRIPTION_TEXT ${StartService} $(DESC_StartService) - !insertmacro MUI_DESCRIPTION_TEXT ${NetworkServiceAccount} $(DESC_NetworkServiceAccount) + !insertmacro MUI_DESCRIPTION_TEXT ${LocalSystemAccount} $(DESC_LocalSystemAccount) !insertmacro MUI_DESCRIPTION_TEXT ${CustomDataFolder} $(DESC_CustomDataFolder) !insertmacro MUI_FUNCTION_DESCRIPTION_END @@ -244,7 +243,7 @@ Function .onInit StrCpy $_INSTALLSERVICE_ "YES" StrCpy $_SERVICESTART_ "YES" StrCpy $_CUSTOMDATAFOLDER_ "NO" - StrCpy $_NETWORKSERVICEACCOUNT_ "NO" + StrCpy $_LOCALSYSTEMACCOUNT_ "NO" StrCpy $_EXISTINGINSTALLATION_ "NO" StrCpy $_EXISTINGSERVICE_ "NO" @@ -281,7 +280,7 @@ Function .onInit ; check if service was run using Network Service account ClearErrors - ReadRegStr "$_NETWORKSERVICEACCOUNT_" HKLM "Software\Jellyfin" "NetworkService" ; in case of error _NETWORKSERVICEACCOUNT_ will be NO as default + ReadRegStr "$_LOCALSYSTEMACCOUNT_" HKLM "Software\Jellyfin" "LocalSystemAccount" ; in case of error _LOCALSYSTEMACCOUNT_ will be NO as default ClearErrors ReadRegStr $_JELLYFINDATADIR_ HKLM "Software\Jellyfin" "DataFolder" ; in case of error, the default holds @@ -289,8 +288,10 @@ Function .onInit ; Hide sections which will not be needed in case of previous install SectionSetText ${InstallService} "" SectionSetText ${StartService} "" - SectionSetText ${NetworkServiceAccount} "" + SectionSetText ${LocalSystemAccount} "" SectionSetText ${CustomDataFolder} "" + SectionSetText ${Advanced} "" + NoService: ; existing install was present but no service was detected @@ -332,10 +333,10 @@ Function .onSelChange SectionGetFlags ${InstallService} $0 ${If} $0 = ${SF_SELECTED} StrCpy $_INSTALLSERVICE_ "YES" - SectionGetFlags ${NetworkServiceAccount} $0 + SectionGetFlags ${LocalSystemAccount} $0 IntOp $0 $0 | ${SF_RO} IntOp $0 $0 ^ ${SF_RO} - SectionSetFlags ${NetworkServiceAccount} $0 + SectionSetFlags ${LocalSystemAccount} $0 SectionGetFlags ${StartService} $0 IntOp $0 $0 | ${SF_RO} IntOp $0 $0 ^ ${SF_RO} @@ -343,7 +344,7 @@ Function .onSelChange ${Else} StrCpy $_INSTALLSERVICE_ "NO" IntOp $0 ${SF_USELECTED} | ${SF_RO} - SectionSetFlags ${NetworkServiceAccount} $0 + SectionSetFlags ${LocalSystemAccount} $0 SectionSetFlags ${StartService} $0 ${EndIf} @@ -354,11 +355,11 @@ Function .onSelChange StrCpy $_SERVICESTART_ "NO" ${EndIf} - SectionGetFlags ${NetworkServiceAccount} $0 + SectionGetFlags ${LocalSystemAccount} $0 ${If} $0 = ${SF_SELECTED} - StrCpy $_NETWORKSERVICEACCOUNT_ "YES" + StrCpy $_LOCALSYSTEMACCOUNT_ "YES" ${Else} - StrCpy $_NETWORKSERVICEACCOUNT_ "NO" + StrCpy $_LOCALSYSTEMACCOUNT_ "NO" ${EndIf} @@ -373,9 +374,13 @@ Function ConfirmationPage Installation Folder : $INSTDIR$\r$\n\ Service install : $_INSTALLSERVICE_$\r$\n\ Service start : $_SERVICESTART_$\r$\n\ - Network Service Account : $_NETWORKSERVICEACCOUNT_$\r$\n\ + Local System account for service: $_LOCALSYSTEMACCOUNT_$\r$\n\ Custom Metadata folder : $_CUSTOMDATAFOLDER_$\r$\n\ Jellyfin Metadata Folder: $_JELLYFINDATADIR_" nsDialogs::Show FunctionEnd + +Function .onInstSuccess + ExecShell "open" "http://localhost:8096" +FunctionEnd