71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""常驻:确保本机有一个可用的独立 Chrome 实例(9223,固定 profile ⇒ 登录态保留)。
|
|
|
|
为什么必须常驻:本机沙箱在父进程退出时连带杀子进程 ⇒ 会话/工具调用里起的浏览器一返回就死。
|
|
为什么放工作区根而不是 tmp/:tmp/ 会被清理,脚本一没计划任务就静默失效。
|
|
|
|
形态:幂等 —— 端口已在听 ⇒ 立刻退出(⛔ 不叠加第二个实例、不抢同一个 profile)。
|
|
由计划任务 `bh-chrome-keepalive` 每 5 分钟触发一次(MultipleInstances=IgnoreNew),
|
|
所以"活着的那份"负责守端口,任务只是兜它挂掉时重新拉起。
|
|
⛔ 不附着用户日常 Chrome(那是 9222,会弹「允许远程调试?」动到用户浏览器)。
|
|
"""
|
|
import os, subprocess, sys, time, socket, io
|
|
|
|
for k in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]:
|
|
os.environ.pop(k, None)
|
|
os.environ["NO_PROXY"] = "127.0.0.1,localhost"
|
|
|
|
WS = r"E:/ProgramData/AIProject/contentm_agent"
|
|
CHROME = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
|
|
PROFILE = r"E:/ProgramData/.workbuddy/tmp/bu-chatgpt-profile"
|
|
PORT = 9223
|
|
LOG = os.path.join(WS, "tmp", "_bh_chrome.log")
|
|
|
|
|
|
def log(msg):
|
|
try:
|
|
os.makedirs(os.path.dirname(LOG), exist_ok=True)
|
|
with io.open(LOG, "a", encoding="utf-8") as f:
|
|
f.write("[%s] %s\n" % (time.strftime("%m-%d %H:%M:%S"), msg))
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def up():
|
|
try:
|
|
s = socket.create_connection(("127.0.0.1", PORT), 1)
|
|
s.close()
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def launch():
|
|
return subprocess.Popen(
|
|
[CHROME, "--remote-debugging-port=%d" % PORT,
|
|
"--user-data-dir=%s" % PROFILE,
|
|
"--no-first-run", "--no-default-browser-check",
|
|
"about:blank"],
|
|
creationflags=0x00000008 | 0x08000000 | 0x00000200, # DETACHED | NO_WINDOW | NEW_PROCESS_GROUP
|
|
)
|
|
|
|
|
|
# ---- 幂等前置:端口已在听 ⇒ 什么都不做 ----
|
|
if up():
|
|
log("port %d already listening ⇒ exit (idempotent)" % PORT)
|
|
sys.exit(0)
|
|
|
|
p = launch()
|
|
log("launched pid=%s" % p.pid)
|
|
|
|
while True:
|
|
time.sleep(5)
|
|
if p.poll() is not None:
|
|
log("chrome exited rc=%s ⇒ relaunch" % p.returncode)
|
|
p = launch()
|
|
log("relaunched pid=%s" % p.pid)
|
|
if not up():
|
|
# ⚠️ 这里只记日志:僵死态(端口不应答、进程不死)按规则由人/会话判定后重启实例,
|
|
# ⛔ 脚本不做自动重启,免得把"正在被人排查的现场"清掉。
|
|
log("port %d not answering (pid alive=%s)" % (PORT, p.poll() is None))
|