Docs: overhaul README, centralize docs, update .gitignore
- Rewrote README.md to highlight PostgreSQL features, installer, and migration, with quick start and full docs index - Moved all markdown documentation files to docs/ for better organization; updated links accordingly - Added .gitignore rules to exclude all PublishProfiles folders; removed tracked publish profile XMLs - Preserved original README as README.original.md; added README_GENERATION.md and DOCUMENTATION_ORGANIZATION.md - Cleaned root directory, improved navigation, and clarified platform-specific instructions
This commit is contained in:
@@ -0,0 +1,590 @@
|
||||
# Creating an Installer for Jellyfin
|
||||
|
||||
**Solution:** E:\Projects\pgsql-jellyfin
|
||||
**Target:** Windows Installer for PostgreSQL-enabled Jellyfin
|
||||
**Status:** Guide for implementation
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
You can create professional installers for your Jellyfin solution using several methods. Here are your options ranked by recommendation:
|
||||
|
||||
---
|
||||
|
||||
## ✅ Recommended: WiX Toolset (Best for Windows)
|
||||
|
||||
### Why WiX?
|
||||
- ✅ Industry standard for .NET applications
|
||||
- ✅ Creates proper MSI installers
|
||||
- ✅ Full Windows Installer features (services, registry, shortcuts)
|
||||
- ✅ Supports upgrades and uninstalls
|
||||
- ✅ Free and open source
|
||||
- ✅ Integrates with Visual Studio
|
||||
|
||||
### Prerequisites
|
||||
```powershell
|
||||
# Install WiX Toolset
|
||||
winget install --id WiX.Toolset
|
||||
|
||||
# Or download from:
|
||||
# https://wixtoolset.org/
|
||||
```
|
||||
|
||||
### Implementation Steps
|
||||
|
||||
#### Step 1: Create WiX Project
|
||||
|
||||
Add to your solution:
|
||||
```xml
|
||||
<!-- Jellyfin.Installer.csproj -->
|
||||
<Project Sdk="WixToolset.Sdk/5.0.0">
|
||||
<PropertyGroup>
|
||||
<OutputType>Package</OutputType>
|
||||
<Platform>x64</Platform>
|
||||
<TargetFramework>net11.0</TargetFramework>
|
||||
<OutputName>JellyfinSetup-PostgreSQL-$(Version)</OutputName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Reference the main Jellyfin.Server project -->
|
||||
<ProjectReference Include="..\Jellyfin.Server\Jellyfin.Server.csproj">
|
||||
<Private>true</Private>
|
||||
<DoNotHarvest>true</DoNotHarvest>
|
||||
<IncludeOutputGroupInVSIXContainer>true</IncludeOutputGroupInVSIXContainer>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
#### Step 2: Create Installer Definition (Product.wxs)
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<Package
|
||||
Name="Jellyfin Server (PostgreSQL Edition)"
|
||||
Manufacturer="Your Name"
|
||||
Version="11.0.0.0"
|
||||
UpgradeCode="PUT-YOUR-GUID-HERE">
|
||||
|
||||
<MajorUpgrade
|
||||
DowngradeErrorMessage="A newer version is already installed." />
|
||||
|
||||
<Media Id="1" Cabinet="jellyfin.cab" EmbedCab="yes" />
|
||||
|
||||
<!-- Installation Directory -->
|
||||
<StandardDirectory Id="ProgramFiles64Folder">
|
||||
<Directory Id="INSTALLFOLDER" Name="Jellyfin">
|
||||
<Directory Id="BinFolder" Name="bin" />
|
||||
<Directory Id="DataFolder" Name="data" />
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
|
||||
<!-- Program Data Directory -->
|
||||
<StandardDirectory Id="CommonAppDataFolder">
|
||||
<Directory Id="ProgramDataFolder" Name="jellyfin" />
|
||||
</StandardDirectory>
|
||||
|
||||
<!-- Components -->
|
||||
<ComponentGroup Id="ProductComponents" Directory="BinFolder">
|
||||
<!-- Harvest all files from lib\Release\net11.0 -->
|
||||
<Component Id="JellyfinExe">
|
||||
<File Source="$(var.SolutionDir)lib\Release\net11.0\jellyfin.dll" />
|
||||
<File Source="$(var.SolutionDir)lib\Release\net11.0\jellyfin.exe" />
|
||||
<!-- Add more files... -->
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
|
||||
<!-- Service Component -->
|
||||
<Component Id="JellyfinService" Directory="BinFolder">
|
||||
<ServiceInstall
|
||||
Id="JellyfinServiceInstaller"
|
||||
Type="ownProcess"
|
||||
Name="JellyfinPostgreSQL"
|
||||
DisplayName="Jellyfin Server (PostgreSQL)"
|
||||
Description="Jellyfin media server with PostgreSQL support"
|
||||
Start="auto"
|
||||
Account="LocalSystem"
|
||||
ErrorControl="normal"
|
||||
Arguments='--service'
|
||||
/>
|
||||
<ServiceControl
|
||||
Id="JellyfinServiceControl"
|
||||
Start="install"
|
||||
Stop="both"
|
||||
Remove="uninstall"
|
||||
Name="JellyfinPostgreSQL"
|
||||
Wait="yes" />
|
||||
</Component>
|
||||
|
||||
<!-- Start Menu Shortcuts -->
|
||||
<StandardDirectory Id="ProgramMenuFolder">
|
||||
<Directory Id="ApplicationProgramsFolder" Name="Jellyfin">
|
||||
<Component Id="ApplicationShortcuts">
|
||||
<Shortcut
|
||||
Id="JellyfinShortcut"
|
||||
Name="Jellyfin Server (PostgreSQL)"
|
||||
Description="Start Jellyfin media server"
|
||||
Target="[BinFolder]jellyfin.exe"
|
||||
WorkingDirectory="BinFolder" />
|
||||
<RemoveFolder Id="CleanUpShortCut" On="uninstall" />
|
||||
</Component>
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
|
||||
<!-- Features -->
|
||||
<Feature Id="ProductFeature" Title="Jellyfin Server" Level="1">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
<ComponentRef Id="JellyfinService" />
|
||||
<ComponentRef Id="ApplicationShortcuts" />
|
||||
</Feature>
|
||||
|
||||
<!-- UI -->
|
||||
<WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
</Package>
|
||||
</Wix>
|
||||
```
|
||||
|
||||
#### Step 3: Build the Installer
|
||||
|
||||
```powershell
|
||||
# Add WiX project to solution
|
||||
dotnet new wix -n Jellyfin.Installer -o Jellyfin.Installer
|
||||
dotnet sln add Jellyfin.Installer/Jellyfin.Installer.csproj
|
||||
|
||||
# Build installer
|
||||
dotnet build Jellyfin.Installer --configuration Release
|
||||
|
||||
# Output: Jellyfin.Installer\bin\Release\JellyfinSetup-PostgreSQL-11.0.0.msi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Quick Option: Inno Setup (Easier but Less Features)
|
||||
|
||||
### Why Inno Setup?
|
||||
- ✅ Very easy to use
|
||||
- ✅ Script-based (no XML)
|
||||
- ✅ Small installer size
|
||||
- ✅ Free
|
||||
- ❌ Less Windows Installer integration than WiX
|
||||
|
||||
### Prerequisites
|
||||
```powershell
|
||||
# Download from: https://jrsoftware.org/isinfo.php
|
||||
winget install --id JRSoftware.InnoSetup
|
||||
```
|
||||
|
||||
### Implementation: Create Setup Script (jellyfin-setup.iss)
|
||||
|
||||
```pascal
|
||||
; Jellyfin PostgreSQL Edition Installer
|
||||
[Setup]
|
||||
AppName=Jellyfin Server (PostgreSQL Edition)
|
||||
AppVersion=11.0.0
|
||||
DefaultDirName={autopf}\Jellyfin
|
||||
DefaultGroupName=Jellyfin
|
||||
OutputDir=installer-output
|
||||
OutputBaseFilename=JellyfinSetup-PostgreSQL-11.0.0
|
||||
Compression=lzma2
|
||||
SolidCompression=yes
|
||||
ArchitecturesAllowed=x64
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
PrivilegesRequired=admin
|
||||
SetupIconFile=jellyfin.ico
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"
|
||||
Name: "service"; Description: "Install as Windows Service"; GroupDescription: "Service Options:"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
; Copy all files from lib\Release\net11.0
|
||||
Source: "lib\Release\net11.0\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
; Copy startup configuration
|
||||
Source: "Jellyfin.Server\Resources\Configuration\startup.windows.json"; DestDir: "{app}"; DestName: "startup.json"; Flags: onlyifdoesntexist
|
||||
|
||||
[Dirs]
|
||||
; Create program data directories
|
||||
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
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"
|
||||
Name: "{group}\Jellyfin Web Interface"; Filename: "http://localhost:8096"
|
||||
Name: "{commondesktop}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
; Open web interface after install
|
||||
Filename: "http://localhost:8096"; Description: "Open Jellyfin Web Interface"; Flags: postinstall shellexec skipifsilent
|
||||
|
||||
; Install as service (optional)
|
||||
Filename: "sc.exe"; Parameters: "create JellyfinPostgreSQL binPath= ""{app}\jellyfin.exe --service"" start= auto"; Tasks: service; Flags: runhidden
|
||||
Filename: "sc.exe"; Parameters: "description JellyfinPostgreSQL ""Jellyfin media server with PostgreSQL support"""; Tasks: service; Flags: runhidden
|
||||
Filename: "sc.exe"; Parameters: "start JellyfinPostgreSQL"; Tasks: service; Flags: runhidden waituntilterminated
|
||||
|
||||
[UninstallRun]
|
||||
; Stop and remove service if it exists
|
||||
Filename: "sc.exe"; Parameters: "stop JellyfinPostgreSQL"; Flags: runhidden
|
||||
Filename: "sc.exe"; Parameters: "delete JellyfinPostgreSQL"; Flags: runhidden
|
||||
|
||||
[Code]
|
||||
// Custom code for install dialogs
|
||||
function InitializeSetup(): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
// Check for .NET 11 runtime
|
||||
if not RegKeyExists(HKLM, 'SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost') then
|
||||
begin
|
||||
MsgBox('.NET 11 Runtime is required. Please install it first.', mbError, MB_OK);
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
```
|
||||
|
||||
### Build Inno Setup Installer
|
||||
|
||||
```powershell
|
||||
# Compile the script
|
||||
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" jellyfin-setup.iss
|
||||
|
||||
# Output: installer-output\JellyfinSetup-PostgreSQL-11.0.0.exe
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Modern Option: MSIX (Windows 10/11 Only)
|
||||
|
||||
### Why MSIX?
|
||||
- ✅ Modern Windows app packaging
|
||||
- ✅ Automatic updates via Microsoft Store
|
||||
- ✅ Clean install/uninstall
|
||||
- ✅ Sandboxed security
|
||||
- ❌ Windows 10 1809+ only
|
||||
- ❌ Requires code signing certificate
|
||||
|
||||
### Implementation: Add MSIX Project
|
||||
|
||||
```xml
|
||||
<!-- Jellyfin.Package.csproj -->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net11.0-windows10.0.19041.0</TargetFramework>
|
||||
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
|
||||
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Jellyfin.Server\Jellyfin.Server.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Images\StoreLogo.png" />
|
||||
<Content Include="Images\Square44x44Logo.png" />
|
||||
<Content Include="Images\Square150x150Logo.png" />
|
||||
<Content Include="Images\Wide310x150Logo.png" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Simple Option: Self-Contained Publish + ZIP
|
||||
|
||||
### Why Zip?
|
||||
- ✅ Simplest approach
|
||||
- ✅ No installer needed
|
||||
- ✅ Portable
|
||||
- ❌ No service install
|
||||
- ❌ No shortcuts
|
||||
- ❌ No uninstaller
|
||||
|
||||
### Implementation
|
||||
|
||||
```powershell
|
||||
# Publish self-contained
|
||||
dotnet publish Jellyfin.Server `
|
||||
--configuration Release `
|
||||
--runtime win-x64 `
|
||||
--self-contained true `
|
||||
--output "publish\jellyfin-pgsql-win-x64" `
|
||||
/p:PublishSingleFile=false `
|
||||
/p:IncludeNativeLibrariesForSelfExtract=true
|
||||
|
||||
# Create ZIP
|
||||
Compress-Archive `
|
||||
-Path "publish\jellyfin-pgsql-win-x64\*" `
|
||||
-DestinationPath "jellyfin-pgsql-11.0.0-win-x64.zip"
|
||||
```
|
||||
|
||||
### Include README in ZIP
|
||||
|
||||
```markdown
|
||||
# Jellyfin Server (PostgreSQL Edition)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Extract this ZIP to C:\Jellyfin (or any location)
|
||||
2. Run `jellyfin.exe`
|
||||
3. Open http://localhost:8096 in your browser
|
||||
4. Follow setup wizard
|
||||
|
||||
## Install as Windows Service
|
||||
|
||||
Run as Administrator:
|
||||
```cmd
|
||||
sc create JellyfinPostgreSQL binPath= "C:\Jellyfin\jellyfin.exe --service" start= auto
|
||||
sc description JellyfinPostgreSQL "Jellyfin media server with PostgreSQL"
|
||||
sc start JellyfinPostgreSQL
|
||||
```
|
||||
|
||||
## Uninstall Service
|
||||
|
||||
```cmd
|
||||
sc stop JellyfinPostgreSQL
|
||||
sc delete JellyfinPostgreSQL
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `startup.json` to customize paths.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Recommended Approach for You
|
||||
|
||||
### For Production Distribution: **WiX Toolset**
|
||||
|
||||
**Why:**
|
||||
- Professional MSI installer
|
||||
- Windows Service support
|
||||
- Proper upgrade handling
|
||||
- Includes PostgreSQL setup guidance
|
||||
|
||||
**Next Steps:**
|
||||
|
||||
1. **Install WiX**
|
||||
```powershell
|
||||
winget install --id WiX.Toolset
|
||||
```
|
||||
|
||||
2. **Create Installer Project**
|
||||
```powershell
|
||||
mkdir Jellyfin.Installer
|
||||
cd Jellyfin.Installer
|
||||
# Create Product.wxs file (see template above)
|
||||
```
|
||||
|
||||
3. **Add to Solution**
|
||||
```powershell
|
||||
dotnet sln add Jellyfin.Installer/Jellyfin.Installer.csproj
|
||||
```
|
||||
|
||||
4. **Build**
|
||||
```powershell
|
||||
dotnet build Jellyfin.Installer --configuration Release
|
||||
```
|
||||
|
||||
### For Quick Testing: **Inno Setup**
|
||||
|
||||
**Why:**
|
||||
- Fast to create
|
||||
- Easy to customize
|
||||
- Good for internal testing
|
||||
|
||||
**Next Steps:**
|
||||
|
||||
1. **Install Inno Setup**
|
||||
```powershell
|
||||
winget install JRSoftware.InnoSetup
|
||||
```
|
||||
|
||||
2. **Create Script**
|
||||
- Use template above
|
||||
- Save as `jellyfin-setup.iss`
|
||||
|
||||
3. **Compile**
|
||||
```powershell
|
||||
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" jellyfin-setup.iss
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Additional Installer Features to Consider
|
||||
|
||||
### PostgreSQL Database Setup
|
||||
|
||||
Add to installer:
|
||||
|
||||
```xml
|
||||
<!-- WiX: Check for PostgreSQL -->
|
||||
<Property Id="POSTGRESQLINSTALLED">
|
||||
<RegistrySearch Id="PostgreSQLSearch"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\PostgreSQL\Installations\postgresql-x64-16"
|
||||
Name="Version"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
|
||||
<Condition Message="PostgreSQL 12+ is required. Please install PostgreSQL first.">
|
||||
Installed OR POSTGRESQLINSTALLED
|
||||
</Condition>
|
||||
```
|
||||
|
||||
### Firewall Rules
|
||||
|
||||
```xml
|
||||
<!-- Add Windows Firewall exception -->
|
||||
<Component Id="FirewallException">
|
||||
<fire:FirewallException Id="JellyfinFirewall"
|
||||
Name="Jellyfin Server"
|
||||
Port="8096"
|
||||
Protocol="tcp"
|
||||
Scope="any" />
|
||||
</Component>
|
||||
```
|
||||
|
||||
### Database Migration Wizard
|
||||
|
||||
Include a post-install wizard for:
|
||||
- PostgreSQL connection setup
|
||||
- Database migration from SQLite
|
||||
- Initial configuration
|
||||
|
||||
---
|
||||
|
||||
## Testing Your Installer
|
||||
|
||||
### Test Checklist
|
||||
|
||||
- [ ] Fresh Windows install
|
||||
- [ ] Upgrade from previous version
|
||||
- [ ] Silent install: `msiexec /i JellyfinSetup.msi /quiet`
|
||||
- [ ] Custom install directory
|
||||
- [ ] Service starts automatically
|
||||
- [ ] Firewall rules created
|
||||
- [ ] Shortcuts work
|
||||
- [ ] Uninstall removes everything
|
||||
- [ ] Data preserved on upgrade
|
||||
|
||||
### Test Commands
|
||||
|
||||
```powershell
|
||||
# Install silently
|
||||
msiexec /i JellyfinSetup-PostgreSQL-11.0.0.msi /quiet /l*v install.log
|
||||
|
||||
# Uninstall silently
|
||||
msiexec /x JellyfinSetup-PostgreSQL-11.0.0.msi /quiet
|
||||
|
||||
# Upgrade
|
||||
msiexec /i JellyfinSetup-PostgreSQL-11.0.1.msi /quiet
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Distribution
|
||||
|
||||
### Code Signing (Recommended)
|
||||
|
||||
Get a code signing certificate:
|
||||
- DigiCert
|
||||
- Sectigo
|
||||
- SignPath (free for open source)
|
||||
|
||||
Sign your installer:
|
||||
```powershell
|
||||
signtool sign /f certificate.pfx /p password /t http://timestamp.digicert.com JellyfinSetup.msi
|
||||
```
|
||||
|
||||
### Release Strategy
|
||||
|
||||
1. **GitHub Releases**
|
||||
```yaml
|
||||
# .github/workflows/release.yml
|
||||
- name: Build Installer
|
||||
run: dotnet build Jellyfin.Installer --configuration Release
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
with:
|
||||
asset_path: Jellyfin.Installer/bin/Release/JellyfinSetup.msi
|
||||
asset_name: jellyfin-pgsql-windows-${{ github.ref }}.msi
|
||||
```
|
||||
|
||||
2. **Versioning**
|
||||
- Use semantic versioning: 11.0.0
|
||||
- Include in filename: JellyfinSetup-PostgreSQL-11.0.0.msi
|
||||
- Update UpgradeCode for major versions only
|
||||
|
||||
---
|
||||
|
||||
## Quick Start Script
|
||||
|
||||
I can create a PowerShell script to help you set up the installer project:
|
||||
|
||||
```powershell
|
||||
# setup-installer.ps1
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("WiX", "InnoSetup", "Both")]
|
||||
[string]$Type = "InnoSetup"
|
||||
)
|
||||
|
||||
Write-Host "Setting up Jellyfin installer project..." -ForegroundColor Cyan
|
||||
|
||||
# Your current setup
|
||||
$solutionRoot = "E:\Projects\pgsql-jellyfin"
|
||||
$libFolder = "$solutionRoot\lib\Release\net11.0"
|
||||
|
||||
if ($Type -eq "InnoSetup" -or $Type -eq "Both") {
|
||||
# Create Inno Setup script
|
||||
# ... (see template above)
|
||||
}
|
||||
|
||||
if ($Type -eq "WiX" -or $Type -eq "Both") {
|
||||
# Create WiX project
|
||||
# ... (see template above)
|
||||
}
|
||||
|
||||
Write-Host "Installer setup complete!" -ForegroundColor Green
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Recommended for You: Inno Setup** (Quick start)
|
||||
- Easiest to implement immediately
|
||||
- Creates professional .exe installer
|
||||
- Includes service install option
|
||||
|
||||
**Future: Migrate to WiX** (Production)
|
||||
- Industry standard
|
||||
- Better upgrade handling
|
||||
- Full MSI features
|
||||
|
||||
**Want me to create the installer project for you?** Just let me know which approach you prefer!
|
||||
|
||||
---
|
||||
|
||||
**Files Needed:**
|
||||
- [ ] jellyfin.ico (icon file)
|
||||
- [ ] License.rtf (license text)
|
||||
- [ ] README.md (user instructions)
|
||||
- [ ] PostgreSQL setup guide
|
||||
|
||||
**Estimated Time:**
|
||||
- Inno Setup: 30 minutes
|
||||
- WiX Setup: 2-4 hours
|
||||
- MSIX: 1-2 hours
|
||||
|
||||
Let me know which installer type you'd like me to help you implement!
|
||||
Reference in New Issue
Block a user