#!/usr/bin/env python3 # -*- coding: utf-8 -*- """项目管理界面的**启动器**(计划任务动作指向它,⛔ 不许直起 `project-board.py`)。 ## 为什么必须有这一层(同族 P0-73/74) · 计划任务的**动作没有 env 字段** ⇒ 变量只能在**进程内**设; · 直接用 `python.exe` 起 ⇒ 控制台程序 ⇒ 计划任务**每次触发闪一个黑窗口**; · 直起业务脚本 ⇒ 将来加变量/判活时**没有落点**,只能再开第二条旁路(闪黑窗的真因)。 ## 本启动器做什么 ① 设好编码与上游地址(⛔ 不依赖宿主 env); ② 调 `project-board.py --serve 20100`; ③ **判活**:端口已在听 ⇒ 直接退出 0(⛔ 不重复起第二实例)。 ⚠️ 必须用 `pythonw.exe` 跑本文件(无控制台 ⇒ 不闪窗)。 """ from __future__ import annotations import os import socket import sys import runpy PORT = int(os.environ.get("DSH_PROJECT_BOARD_PORT") or "20100") HERE = os.path.dirname(os.path.abspath(__file__)) TARGET = os.path.join(HERE, "project-board.py") # ── 变量只在这里设(计划任务动作没有 env 字段)── os.environ.setdefault("PYTHONIOENCODING", "utf-8") os.environ.setdefault("DSH_PROJECT_BOARD_UPSTREAM", "http://127.0.0.1:20099/board.json") # 🔴 「本工作区」=**拥有一这层的那个工作区**(用户 2026-10-06 要:本工作区的卡片换色突出)。 # ⛔ 不许靠 `Path.cwd()`:计划任务的 **工作目录是 `交付物/项目管理界面`**(实测), # 不是工作区根 ⇒ 那样算出来的"本工作区"是错的。 # 正解=从本文件位置**往上两级**:`/交付物/项目管理界面/project-board-launch.py`。 os.environ.setdefault("DSH_PM_BOARD_SELF_WS", os.path.dirname(os.path.dirname(HERE))) def port_listening(port: int) -> bool: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(0.4) try: return s.connect_ex(("127.0.0.1", port)) == 0 finally: s.close() def main() -> int: if port_listening(PORT): return 0 # 已在跑 ⇒ 静默退出(⛔ 不起第二实例) sys.argv = [TARGET, "--serve", str(PORT)] try: runpy.run_path(TARGET, run_name="__main__") except SystemExit: raise except Exception: return 1 return 0 if __name__ == "__main__": sys.exit(main())