402183765c
- Rewrite tray to run on main thread (pystray owns message loop, uvicorn in background thread) — fixes unresponsive confirmation dialogs - Use native Windows MessageBoxW instead of tkinter (embedded Python has no tkinter) - Pin numpy <2.0 to fix soundcard's numpy.fromstring (removed in 2.0) - Strip transitive numpy 2.x wheels in build script - Installer copies config.example.yaml as config.yaml on fresh install - Suppress noisy screen_brightness_control warnings
168 lines
5.8 KiB
NSIS
168 lines
5.8 KiB
NSIS
; Media Server NSIS Installer
|
|
; Cross-compilable: apt install nsis && makensis -DVERSION="1.0.0" installer.nsi
|
|
|
|
!include "MUI2.nsh"
|
|
!include "FileFunc.nsh"
|
|
|
|
; --- Configuration ---
|
|
!define APPNAME "Media Server"
|
|
!define EXENAME "media-server.bat"
|
|
!define VBSNAME "start-hidden.vbs"
|
|
!ifndef VERSION
|
|
!define VERSION "0.0.0"
|
|
!endif
|
|
|
|
Name "${APPNAME} ${VERSION}"
|
|
OutFile "build\MediaServer-v${VERSION}-setup.exe"
|
|
InstallDir "$LOCALAPPDATA\${APPNAME}"
|
|
RequestExecutionLevel user
|
|
|
|
; --- UI ---
|
|
!define MUI_ICON "media_server\static\icons\icon.ico"
|
|
!define MUI_UNICON "media_server\static\icons\icon.ico"
|
|
!define MUI_ABORTWARNING
|
|
!define MUI_FINISHPAGE_RUN ""
|
|
!define MUI_FINISHPAGE_RUN_TEXT "Launch ${APPNAME}"
|
|
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
|
|
|
|
!insertmacro MUI_PAGE_WELCOME
|
|
!insertmacro MUI_PAGE_DIRECTORY
|
|
!insertmacro MUI_PAGE_COMPONENTS
|
|
!insertmacro MUI_PAGE_INSTFILES
|
|
!insertmacro MUI_PAGE_FINISH
|
|
|
|
!insertmacro MUI_UNPAGE_CONFIRM
|
|
!insertmacro MUI_UNPAGE_INSTFILES
|
|
|
|
!insertmacro MUI_LANGUAGE "English"
|
|
|
|
; --- Functions ---
|
|
Function LaunchApp
|
|
ExecShell "open" "wscript.exe" '"$INSTDIR\scripts\${VBSNAME}"'
|
|
; Give the server a moment to start, then open the UI in the default browser
|
|
Sleep 2000
|
|
ExecShell "open" "http://localhost:8765/"
|
|
FunctionEnd
|
|
|
|
Function .onInit
|
|
; Check if server is running by trying to open its Python executable exclusively
|
|
IfFileExists "$INSTDIR\python\python.exe" 0 done
|
|
ClearErrors
|
|
FileOpen $0 "$INSTDIR\python\python.exe" a
|
|
IfErrors locked
|
|
; File opened fine — server is not running
|
|
FileClose $0
|
|
Goto done
|
|
locked:
|
|
MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
|
|
"${APPNAME} is currently running.$\n$\nYes = Stop the server and continue$\nNo = Continue without stopping (may cause errors)$\nCancel = Abort installation" \
|
|
IDYES kill IDNO done
|
|
Abort
|
|
kill:
|
|
nsExec::ExecToLog 'wmic process where "ExecutablePath like $\'%Media Server%python%$\'" call terminate'
|
|
Sleep 2000
|
|
done:
|
|
FunctionEnd
|
|
|
|
; --- Sections ---
|
|
Section "!Core (required)" SecCore
|
|
SectionIn RO
|
|
|
|
SetOutPath "$INSTDIR"
|
|
|
|
; Copy entire distribution
|
|
File /r "dist\media-server\*.*"
|
|
|
|
; Create config.yaml from example if it doesn't already exist (preserve user config on upgrade)
|
|
IfFileExists "$INSTDIR\config.yaml" +2
|
|
CopyFiles /SILENT "$INSTDIR\config.example.yaml" "$INSTDIR\config.yaml"
|
|
|
|
; Create uninstaller
|
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
|
|
|
; Start Menu shortcuts
|
|
CreateDirectory "$SMPROGRAMS\${APPNAME}"
|
|
CreateShortcut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" \
|
|
"wscript.exe" '"$INSTDIR\scripts\${VBSNAME}"' \
|
|
"$INSTDIR\python\python.exe" 0
|
|
CreateShortcut "$SMPROGRAMS\${APPNAME}\${APPNAME} (Console).lnk" \
|
|
"$INSTDIR\${EXENAME}" "" \
|
|
"$INSTDIR\python\python.exe" 0
|
|
CreateShortcut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" \
|
|
"$INSTDIR\uninstall.exe"
|
|
|
|
; Registry for Add/Remove Programs
|
|
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"DisplayName" "${APPNAME}"
|
|
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"DisplayVersion" "${VERSION}"
|
|
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"UninstallString" "$\"$INSTDIR\uninstall.exe$\""
|
|
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"InstallLocation" "$INSTDIR"
|
|
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"Publisher" "Alexei Dolgolyov"
|
|
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"NoModify" 1
|
|
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"NoRepair" 1
|
|
|
|
; Calculate installed size
|
|
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
|
IntFmt $0 "0x%08X" $0
|
|
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
|
"EstimatedSize" "$0"
|
|
SectionEnd
|
|
|
|
Section "Desktop shortcut" SecDesktop
|
|
CreateShortcut "$DESKTOP\${APPNAME}.lnk" \
|
|
"wscript.exe" '"$INSTDIR\scripts\${VBSNAME}"' \
|
|
"$INSTDIR\python\python.exe" 0
|
|
SectionEnd
|
|
|
|
Section "Start with Windows" SecAutostart
|
|
; Create Startup folder shortcut (runs hidden via VBS)
|
|
CreateShortcut "$SMSTARTUP\${APPNAME}.lnk" \
|
|
"wscript.exe" '"$INSTDIR\scripts\${VBSNAME}"' \
|
|
"$INSTDIR\python\python.exe" 0
|
|
SectionEnd
|
|
|
|
; --- Section descriptions ---
|
|
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecCore} \
|
|
"Core application files, embedded Python, and Start Menu shortcuts."
|
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} \
|
|
"Create a desktop shortcut to launch ${APPNAME}."
|
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecAutostart} \
|
|
"Automatically start ${APPNAME} when you log in to Windows."
|
|
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
|
|
|
; --- Uninstaller ---
|
|
Section "Uninstall"
|
|
; Stop running instance
|
|
nsExec::ExecToLog 'wmic process where "ExecutablePath like $\'%Media Server%python%$\'" call terminate'
|
|
nsExec::ExecToLog 'taskkill /F /IM media-server.exe'
|
|
|
|
; Remove application files
|
|
RMDir /r "$INSTDIR\python"
|
|
RMDir /r "$INSTDIR\app"
|
|
RMDir /r "$INSTDIR\scripts"
|
|
Delete "$INSTDIR\${EXENAME}"
|
|
Delete "$INSTDIR\VERSION"
|
|
Delete "$INSTDIR\uninstall.exe"
|
|
|
|
; Preserve config.yaml (user data) — only remove the example
|
|
Delete "$INSTDIR\config.example.yaml"
|
|
|
|
; Remove shortcuts
|
|
Delete "$DESKTOP\${APPNAME}.lnk"
|
|
Delete "$SMSTARTUP\${APPNAME}.lnk"
|
|
RMDir /r "$SMPROGRAMS\${APPNAME}"
|
|
|
|
; Remove registry
|
|
DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
|
|
|
|
; Remove install dir only if empty (config.yaml may remain)
|
|
RMDir "$INSTDIR"
|
|
SectionEnd
|