import os import signal import subprocess import sys import time from pathlib import Path ROOT = Path(__file__).resolve().parent VIDEO = "testhd2_edit.mp4" CHILDREN: list[subprocess.Popen] = [] STOPPING = False def kill_tree(pid: int) -> None: try: subprocess.run( ["taskkill", "/PID", str(pid), "/T", "/F"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, ) except Exception: pass def pids_listening_on_port(port: int) -> list[int]: try: result = subprocess.run( ["netstat", "-ano", "-p", "tcp"], capture_output=True, text=True, encoding="utf-8", errors="replace", check=False, ) except Exception: return [] pids: set[int] = set() suffix = f":{port}" for raw_line in result.stdout.splitlines(): line = raw_line.strip() if not line: continue parts = line.split() if len(parts) < 5: continue proto, local_addr, _, state, pid_text = parts[:5] if proto.upper() != "TCP": continue if state.upper() != "LISTENING": continue if not local_addr.endswith(suffix): continue try: pids.add(int(pid_text)) except ValueError: continue return sorted(pids) def preflight_cleanup() -> None: stale_pids = pids_listening_on_port(8088) for pid in stale_pids: print(f"Pulizia preventiva: termino processo in ascolto su 8088 (PID {pid})", flush=True) kill_tree(pid) if stale_pids: time.sleep(0.4) def stop_all() -> None: global STOPPING if STOPPING: return STOPPING = True print("\nArresto finestre demo...", flush=True) for proc in CHILDREN: if proc.poll() is None: kill_tree(proc.pid) def on_signal(signum, frame) -> None: stop_all() raise KeyboardInterrupt def start_window(title: str, launcher_bat: str) -> subprocess.Popen: startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = 6 # SW_MINIMIZE return subprocess.Popen( ["cmd.exe", "/k", launcher_bat], cwd=str(ROOT), creationflags=subprocess.CREATE_NEW_CONSOLE, startupinfo=startupinfo, ) def main() -> int: signal.signal(signal.SIGINT, on_signal) if hasattr(signal, "SIGTERM"): signal.signal(signal.SIGTERM, on_signal) preflight_cleanup() try: print("Avvio WMS server...", flush=True) CHILDREN.append(start_window("FlyWMS - WMS Server", "run_wms_server.bat")) time.sleep(0.25) print("Avvio observer...", flush=True) CHILDREN.append(start_window("FlyWMS - Observer", "run_observer.bat")) time.sleep(0.25) print("Avvio navigator...", flush=True) CHILDREN.append(start_window("FlyWMS - Navigator", "run_navigator.bat")) print("\nDemo avviata.", flush=True) for proc in CHILDREN: print(f"- PID {proc.pid}", flush=True) print("\nPremi Ctrl+C in questa finestra per chiudere tutto.\n", flush=True) while True: alive = [proc for proc in CHILDREN if proc.poll() is None] if not alive: print("Tutte le finestre demo sono terminate.", flush=True) return 0 time.sleep(1.0) except KeyboardInterrupt: print("Interruzione rilevata.", flush=True) return 130 finally: stop_all() if __name__ == "__main__": raise SystemExit(main())