feat: improve installer with custom icon, launch-after-install, and running-instance detection
Lint & Test / test (push) Successful in 9s
Lint & Test / test (push) Successful in 9s
- Use custom icon.ico for installer/uninstaller UI - LaunchApp opens server then browser after install - .onInit detects running instance and offers to stop it - Use WMIC-based process kill targeting embedded Python path - start-hidden.vbs prefers embedded Python over system Python - Add pystray dependency to build script - CLAUDE.md: note to consult CI/CD guide for build changes
This commit is contained in:
@@ -166,6 +166,8 @@ Uninstall preserves `config.yaml` (user data).
|
|||||||
|
|
||||||
Reference: [gitea-python-ci-cd.md](https://git.dolgolyov-family.by/alexei.dolgolyov/claude-code-facts/src/branch/main/gitea-python-ci-cd.md)
|
Reference: [gitea-python-ci-cd.md](https://git.dolgolyov-family.by/alexei.dolgolyov/claude-code-facts/src/branch/main/gitea-python-ci-cd.md)
|
||||||
|
|
||||||
|
**IMPORTANT:** When modifying CI/CD workflows, `installer.nsi`, or build scripts (`build-dist-*.sh`), always fetch and consult the guide above first to ensure changes stay in sync with established patterns.
|
||||||
|
|
||||||
### Before Pushing
|
### Before Pushing
|
||||||
|
|
||||||
Ensure CI will pass locally:
|
Ensure CI will pass locally:
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ WIN_DEPS=(
|
|||||||
"pycaw>=20230407"
|
"pycaw>=20230407"
|
||||||
"screen-brightness-control>=0.20.0"
|
"screen-brightness-control>=0.20.0"
|
||||||
"monitorcontrol>=3.0.0"
|
"monitorcontrol>=3.0.0"
|
||||||
|
"pystray>=0.19.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Visualizer dependencies
|
# Visualizer dependencies
|
||||||
|
|||||||
+34
-9
@@ -18,13 +18,12 @@ InstallDir "$LOCALAPPDATA\${APPNAME}"
|
|||||||
RequestExecutionLevel user
|
RequestExecutionLevel user
|
||||||
|
|
||||||
; --- UI ---
|
; --- UI ---
|
||||||
; To use a custom icon, convert icon.svg to icon.ico and uncomment:
|
!define MUI_ICON "media_server\static\icons\icon.ico"
|
||||||
; !define MUI_ICON "media_server\static\icons\icon.ico"
|
!define MUI_UNICON "media_server\static\icons\icon.ico"
|
||||||
; !define MUI_UNICON "media_server\static\icons\icon.ico"
|
|
||||||
!define MUI_ABORTWARNING
|
!define MUI_ABORTWARNING
|
||||||
!define MUI_FINISHPAGE_RUN "wscript.exe"
|
!define MUI_FINISHPAGE_RUN ""
|
||||||
!define MUI_FINISHPAGE_RUN_PARAMETERS '"$INSTDIR\scripts\${VBSNAME}"'
|
|
||||||
!define MUI_FINISHPAGE_RUN_TEXT "Launch ${APPNAME}"
|
!define MUI_FINISHPAGE_RUN_TEXT "Launch ${APPNAME}"
|
||||||
|
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_WELCOME
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
@@ -37,13 +36,38 @@ RequestExecutionLevel user
|
|||||||
|
|
||||||
!insertmacro MUI_LANGUAGE "English"
|
!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 ---
|
; --- Sections ---
|
||||||
Section "!Core (required)" SecCore
|
Section "!Core (required)" SecCore
|
||||||
SectionIn RO
|
SectionIn RO
|
||||||
|
|
||||||
; Stop running instance if any
|
|
||||||
nsExec::ExecToLog 'taskkill /F /IM python.exe /FI "WINDOWTITLE eq media_server*"'
|
|
||||||
|
|
||||||
SetOutPath "$INSTDIR"
|
SetOutPath "$INSTDIR"
|
||||||
|
|
||||||
; Copy entire distribution
|
; Copy entire distribution
|
||||||
@@ -112,7 +136,8 @@ SectionEnd
|
|||||||
; --- Uninstaller ---
|
; --- Uninstaller ---
|
||||||
Section "Uninstall"
|
Section "Uninstall"
|
||||||
; Stop running instance
|
; Stop running instance
|
||||||
nsExec::ExecToLog 'taskkill /F /IM python.exe /FI "WINDOWTITLE eq media_server*"'
|
nsExec::ExecToLog 'wmic process where "ExecutablePath like $\'%Media Server%python%$\'" call terminate'
|
||||||
|
nsExec::ExecToLog 'taskkill /F /IM media-server.exe'
|
||||||
|
|
||||||
; Remove application files
|
; Remove application files
|
||||||
RMDir /r "$INSTDIR\python"
|
RMDir /r "$INSTDIR\python"
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 208 B |
@@ -1,7 +1,13 @@
|
|||||||
|
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||||
Set WshShell = CreateObject("WScript.Shell")
|
Set WshShell = CreateObject("WScript.Shell")
|
||||||
' Get the directory of this script (scripts\), then go up to media-server root
|
' Get the directory of this script (scripts\), then go up to media-server root
|
||||||
scriptDir = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)
|
scriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||||
serverRoot = CreateObject("Scripting.FileSystemObject").GetParentFolderName(scriptDir)
|
serverRoot = fso.GetParentFolderName(scriptDir)
|
||||||
WshShell.CurrentDirectory = serverRoot
|
WshShell.CurrentDirectory = serverRoot
|
||||||
' Run python completely hidden (0 = hidden, False = don't wait)
|
' Use embedded Python if present (installed distribution), otherwise system Python
|
||||||
WshShell.Run "python -m media_server.main", 0, False
|
embeddedPython = serverRoot & "\python\python.exe"
|
||||||
|
If fso.FileExists(embeddedPython) Then
|
||||||
|
WshShell.Run """" & embeddedPython & """ -m media_server.main", 0, False
|
||||||
|
Else
|
||||||
|
WshShell.Run "python -m media_server.main", 0, False
|
||||||
|
End If
|
||||||
|
|||||||
Reference in New Issue
Block a user