; Jellyfin Server (PostgreSQL Edition) Installer Script ; Generated for: E:\Projects\pgsql-jellyfin ; Build with Inno Setup 6: https://jrsoftware.org/isinfo.php [Setup] ; Basic Application Information AppName=Jellyfin Server (PostgreSQL Edition) AppVersion=11.0.0-PostgreSQL-PREVIEW AppPublisher=Your Name AppPublisherURL=https://your-website.com AppSupportURL=https://your-website.com AppUpdatesURL=https://your-website.com DefaultDirName={autopf}\Jellyfin-PostgreSQL DefaultGroupName=Jellyfin PostgreSQL AllowNoIcons=yes OutputDir=installer-output OutputBaseFilename=JellyfinSetup-PostgreSQL-11.0.0-PREVIEW Compression=lzma2 SolidCompression=yes ArchitecturesAllowed=x64compatible ArchitecturesInstallIn64BitMode=x64compatible PrivilegesRequired=admin SetupIconFile=jellyfin.ico UninstallDisplayIcon={app}\jellyfin.exe WizardStyle=modern DisableProgramGroupPage=yes [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked Name: "service"; Description: "Install as Windows Service (runs automatically on startup)"; GroupDescription: "Service Options:"; Flags: unchecked Name: "firewall"; Description: "Add Windows Firewall exception"; GroupDescription: "Network Options:"; Flags: unchecked [Files] ; ============================================================================ ; Application Files ; ============================================================================ ; Copy all files from lib\Release\net11.0 (includes SQL files automatically) Source: "lib\Release\net11.0\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; ============================================================================ ; Configuration Files ; ============================================================================ ; Copy startup configuration with Windows defaults Source: "Jellyfin.Server\Resources\Configuration\startup.windows.json"; DestDir: "{commonappdata}\jellyfin"; DestName: "startup.json"; Flags: onlyifdoesntexist ; ============================================================================ ; Database Management Scripts ; ============================================================================ ; PowerShell scripts for database management Source: "db-config.ps1"; DestDir: "{app}"; Flags: ignoreversion Source: "Fix-ItemValues-Performance.ps1"; DestDir: "{app}"; Flags: ignoreversion Source: "db-quick.ps1"; DestDir: "{app}"; Flags: ignoreversion Source: "Add-All-Indexes.bat"; DestDir: "{app}"; Flags: ignoreversion ; ============================================================================ ; Documentation ; ============================================================================ ; Essential documentation Source: "README.md"; DestDir: "{app}"; Flags: isreadme; DestName: "README.txt" Source: "docs\START_HERE.md"; DestDir: "{app}\docs"; DestName: "START_HERE.txt" Source: "docs\QUICKSTART_POSTGRESQL.md"; DestDir: "{app}\docs"; DestName: "QUICKSTART_POSTGRESQL.txt" Source: "docs\INSTALLER_GUIDE.md"; DestDir: "{app}\docs"; DestName: "INSTALLER_GUIDE.txt" Source: "docs\QUICK_REFERENCE.md"; DestDir: "{app}\docs"; DestName: "QUICK_REFERENCE.txt" ; Performance and troubleshooting Source: "docs\ADD_INDEXES_GUIDE.md"; DestDir: "{app}\docs"; DestName: "ADD_INDEXES_GUIDE.txt" Source: "docs\DIAGNOSTICS_COMPLETE_SUMMARY.md"; DestDir: "{app}\docs"; DestName: "DIAGNOSTICS_COMPLETE_SUMMARY.txt" Source: "docs\POSTGRESQL_TROUBLESHOOTING.md"; DestDir: "{app}\docs"; DestName: "POSTGRESQL_TROUBLESHOOTING.txt" [Dirs] ; Create program data directories with proper permissions Name: "{commonappdata}\jellyfin"; Permissions: users-modify Name: "{commonappdata}\jellyfin\data"; Permissions: users-modify Name: "{commonappdata}\jellyfin\log"; Permissions: users-modify Name: "{commonappdata}\jellyfin\cache"; Permissions: users-modify Name: "{commonappdata}\jellyfin\config"; Permissions: users-modify Name: "{commonappdata}\jellyfin\web"; Permissions: users-modify [Icons] ; ============================================================================ ; Start Menu Shortcuts ; ============================================================================ ; Application shortcuts Name: "{group}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; WorkingDir: "{app}"; Comment: "Start Jellyfin media server" Name: "{group}\Jellyfin Web Interface"; Filename: "http://localhost:8096"; Comment: "Open Jellyfin in web browser" ; Data and logs Name: "{group}\Jellyfin Logs"; Filename: "{commonappdata}\jellyfin\log"; Comment: "View Jellyfin log files" Name: "{group}\Jellyfin Data"; Filename: "{commonappdata}\jellyfin"; Comment: "Jellyfin data directory" ; Documentation and tools Name: "{group}\Documentation"; Filename: "{app}\docs"; Comment: "View Jellyfin documentation" Name: "{group}\Database Tools"; Filename: "powershell.exe"; Parameters: "-ExecutionPolicy Bypass -File ""{app}\db-quick.ps1"""; WorkingDir: "{app}"; Comment: "Database management tools" ; Uninstall Name: "{group}\{cm:UninstallProgram,Jellyfin PostgreSQL}"; Filename: "{uninstallexe}" ; Desktop shortcut (optional) Name: "{commondesktop}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; WorkingDir: "{app}"; Tasks: desktopicon [Run] ; Add firewall rule Filename: "netsh.exe"; Parameters: "advfirewall firewall add rule name=""Jellyfin Server"" dir=in action=allow protocol=TCP localport=8096"; Flags: runhidden; Tasks: firewall ; Install and start service Filename: "sc.exe"; Parameters: "create JellyfinPostgreSQL binPath= ""{app}\jellyfin.exe --service --datadir {commonappdata}\jellyfin"" start= auto displayname= ""Jellyfin Server (PostgreSQL)"""; Flags: runhidden; Tasks: service Filename: "sc.exe"; Parameters: "description JellyfinPostgreSQL ""Jellyfin media server with PostgreSQL support"""; Flags: runhidden; Tasks: service Filename: "sc.exe"; Parameters: "start JellyfinPostgreSQL"; Flags: runhidden waituntilterminated; Tasks: service ; Open web interface after install (if not running as service) Filename: "http://localhost:8096"; Description: "Open Jellyfin Web Interface"; Flags: postinstall shellexec skipifsilent nowait; Check: not WizardIsTaskSelected('service') [UninstallRun] ; Stop and remove service Filename: "sc.exe"; Parameters: "stop JellyfinPostgreSQL"; Flags: runhidden Filename: "sc.exe"; Parameters: "delete JellyfinPostgreSQL"; Flags: runhidden ; Remove firewall rule Filename: "netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Jellyfin Server"""; Flags: runhidden [UninstallDelete] ; Clean up log files (optional) Type: filesandordirs; Name: "{commonappdata}\jellyfin\log" [Code] var PostgreSQLPage: TInputQueryWizardPage; DataDirPage: TInputDirWizardPage; // Check for .NET 11 Runtime function IsDotNetInstalled: Boolean; var Success: Boolean; ResultCode: Integer; begin // Check for .NET 11 runtime Success := RegKeyExists(HKLM64, 'SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\11.0.0-preview.1.26104.118'); if not Success then begin MsgBox('.NET 11 Runtime is required but not found.' + #13#10 + #13#10 + 'Please download and install it from:' + #13#10 + 'https://dotnet.microsoft.com/download/dotnet/11.0' + #13#10 + #13#10 + 'Installation will continue, but Jellyfin will not run until .NET 11 is installed.', mbInformation, MB_OK); end; Result := True; // Allow installation to continue end; // Check for PostgreSQL function IsPostgreSQLInstalled: Boolean; begin Result := RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-18') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-17') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-16') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-15') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-14') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-13') or RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-12'); end; procedure InitializeWizard; begin // Check .NET IsDotNetInstalled; // PostgreSQL configuration page PostgreSQLPage := CreateInputQueryPage(wpSelectTasks, 'PostgreSQL Database Configuration', 'Enter your PostgreSQL connection details', 'Jellyfin will store its data in PostgreSQL. If you haven''t installed PostgreSQL yet, ' + 'you can skip this and configure it later in the startup.json file.'); PostgreSQLPage.Add('PostgreSQL Host:', False); PostgreSQLPage.Add('PostgreSQL Port:', False); PostgreSQLPage.Add('Database Name:', False); PostgreSQLPage.Add('Username:', False); PostgreSQLPage.Add('Password:', True); // Default values PostgreSQLPage.Values[0] := 'localhost'; PostgreSQLPage.Values[1] := '5432'; PostgreSQLPage.Values[2] := 'jellyfin'; PostgreSQLPage.Values[3] := 'jellyfin'; PostgreSQLPage.Values[4] := ''; // Show warning if PostgreSQL not detected if not IsPostgreSQLInstalled then begin MsgBox('PostgreSQL was not detected on your system.' + #13#10 + #13#10 + 'Jellyfin requires PostgreSQL 12 or later.' + #13#10 + 'Download from: https://www.postgresql.org/download/windows/' + #13#10 + #13#10 + 'You can still install Jellyfin and configure PostgreSQL later.', mbInformation, MB_OK); end; end; function ShouldSkipPage(PageID: Integer): Boolean; begin Result := False; // Skip PostgreSQL page if user is upgrading if (PageID = PostgreSQLPage.ID) and WizardSilent then Result := True; end; procedure CurStepChanged(CurStep: TSetupStep); var StartupConfigPath: String; ConfigLines: TArrayOfString; I: Integer; ConfigContent: AnsiString; begin if CurStep = ssPostInstall then begin // Create/update startup.json with PostgreSQL connection string if provided if PostgreSQLPage.Values[4] <> '' then begin StartupConfigPath := ExpandConstant('{commonappdata}\jellyfin\startup.json'); // Note: In a production installer, you'd want to properly parse and update JSON // For simplicity, this example just shows where you'd add the logic // Create a connection string file ConfigContent := 'Host=' + PostgreSQLPage.Values[0] + ';' + 'Port=' + PostgreSQLPage.Values[1] + ';' + 'Database=' + PostgreSQLPage.Values[2] + ';' + 'Username=' + PostgreSQLPage.Values[3] + ';' + 'Password=' + PostgreSQLPage.Values[4]; SaveStringToFile(ExpandConstant('{commonappdata}\jellyfin\pgsql-connection.txt'), ConfigContent, False); end; end; end; // Custom finish page message procedure CurPageChanged(CurPageID: Integer); begin if CurPageID = wpFinished then begin WizardForm.FinishedLabel.Caption := 'Jellyfin Server has been successfully installed!' + #13#10 + #13#10; if WizardIsTaskSelected('service') then WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption + 'The Jellyfin service is now running. Open your browser to:' + #13#10 + 'http://localhost:8096' + #13#10 + #13#10 else WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption + 'Click Finish to close Setup. You can start Jellyfin from the Start Menu.' + #13#10 + #13#10; WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption + 'Important Notes:' + #13#10 + '• Data directory: ' + ExpandConstant('{commonappdata}\jellyfin') + #13#10 + '• Configuration: ' + ExpandConstant('{commonappdata}\jellyfin\startup.json') + #13#10 + '• Logs: ' + ExpandConstant('{commonappdata}\jellyfin\log') + #13#10; if not IsPostgreSQLInstalled then WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption + #13#10 + '⚠ Remember to install PostgreSQL 12+ and configure the connection!'; end; end;