From 415231f2f29e41bc816fe80f0cd8788d833bfb6a Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 24 Mar 2026 15:26:14 +0300 Subject: [PATCH] fix: tray restart uses python -m for reliable process respawn The previous os.execv approach and console_script detection both failed on Windows. Now restart always spawns `python -m media_server.main` via subprocess.Popen with start_new_session, which works regardless of how the server was originally started. --- media_server/main.py | 14 ++++++++++++++ media_server/tray.py | 11 ++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/media_server/main.py b/media_server/main.py index f472969..c7f0f88 100644 --- a/media_server/main.py +++ b/media_server/main.py @@ -277,6 +277,20 @@ def main(): # Tray exited — wait for server to finish graceful shutdown server_thread.join(timeout=10) + + if tray.restart_requested: + import subprocess + + # Always restart via `python -m media_server.main` — this works + # regardless of how we were originally started (console_script, + # python -m, or direct script invocation). + cmd = [sys.executable, "-m", "media_server.main"] + + subprocess.Popen( + cmd, + cwd=Path.cwd(), + start_new_session=True, + ) else: uvicorn.run( "media_server.main:app", diff --git a/media_server/tray.py b/media_server/tray.py index 93ef8b3..400a7fb 100644 --- a/media_server/tray.py +++ b/media_server/tray.py @@ -3,8 +3,6 @@ import ctypes import io import logging -import os -import sys import webbrowser from pathlib import Path from typing import Callable @@ -125,10 +123,13 @@ class TrayManager: if not _confirm("Media Server", "Restart the server?"): return logger.info("Restart requested from tray") - self._icon.stop() + self._restart_requested = True self._on_exit() - os.environ["MEDIA_SERVER_RESTART"] = "1" - os.execv(sys.executable, [sys.executable] + sys.argv) + self._icon.stop() + + @property + def restart_requested(self) -> bool: + return getattr(self, "_restart_requested", False) def _shutdown(self, icon: "pystray.Icon", item: "pystray.MenuItem") -> None: if not _confirm("Media Server", "Shut down the server?"):