fix: reuse browser, harden session restore without URL clash (v2.0.27)
Some checks failed
技能自动化发布 / release (push) Has been cancelled
Some checks failed
技能自动化发布 / release (push) Has been cancelled
This commit is contained in:
@@ -192,6 +192,51 @@ def cmd_reveal_profile(account_id):
|
||||
)
|
||||
|
||||
|
||||
def _list_profile_browser_pids(profile_dir: str):
|
||||
"""找出已占用本 Profile 的 chrome/msedge PID(与采集技能同逻辑)。"""
|
||||
import json as _json
|
||||
|
||||
profile_abs = os.path.abspath(profile_dir)
|
||||
needle = os.path.normcase(profile_abs)
|
||||
if sys.platform != "win32":
|
||||
return []
|
||||
ps = (
|
||||
"Get-CimInstance Win32_Process -Filter "
|
||||
"\"name='chrome.exe' or name='msedge.exe'\" |"
|
||||
" Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"
|
||||
)
|
||||
try:
|
||||
completed = subprocess.run(
|
||||
["powershell", "-NoProfile", "-Command", ps],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=20,
|
||||
check=False,
|
||||
)
|
||||
except Exception:
|
||||
return []
|
||||
raw = (completed.stdout or "").strip()
|
||||
if not raw:
|
||||
return []
|
||||
try:
|
||||
payload = _json.loads(raw)
|
||||
except Exception:
|
||||
return []
|
||||
rows = payload if isinstance(payload, list) else [payload]
|
||||
pids = []
|
||||
for row in rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
cmdline = str(row.get("CommandLine") or "")
|
||||
if needle not in os.path.normcase(cmdline):
|
||||
continue
|
||||
try:
|
||||
pids.append(int(row.get("ProcessId")))
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
return sorted(set(pids))
|
||||
|
||||
|
||||
def cmd_open(account_id):
|
||||
"""
|
||||
打开该账号的持久化浏览器,仅用于肉眼核对 / 手工登录 / 抓 DOM。
|
||||
@@ -226,6 +271,39 @@ def cmd_open(account_id):
|
||||
profile_abs = os.path.abspath(profile_dir)
|
||||
os.makedirs(profile_abs, exist_ok=True)
|
||||
|
||||
existing = _list_profile_browser_pids(profile_abs)
|
||||
if existing:
|
||||
log.info(
|
||||
"browser_open_reuse account_id=%s profile_dir=%s pids=%s",
|
||||
account_id,
|
||||
profile_abs,
|
||||
existing,
|
||||
)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "result",
|
||||
"schema_version": 1,
|
||||
"status": "success",
|
||||
"message": "已复用打开中的浏览器窗口",
|
||||
"success": True,
|
||||
"data": {
|
||||
"account_id": int(target["id"]) if target.get("id") is not None else account_id,
|
||||
"account_label": target.get("account_label"),
|
||||
"browser": "Google Chrome",
|
||||
"browser_exe": browser_exe,
|
||||
"profile_dir": profile_abs,
|
||||
"url": resolve_account_browser_url(target),
|
||||
"pid": existing[0],
|
||||
"reused": True,
|
||||
"pids": existing,
|
||||
},
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
# 独立 Profile 默认不会「继续上次会话」,Session Cookie 关窗即丢;打开前写入 Preferences
|
||||
prefs_result = ensure_session_restore(profile_abs)
|
||||
log.info("browser_open_prefs %s", prefs_result)
|
||||
@@ -236,14 +314,22 @@ def cmd_open(account_id):
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
# 与 profile_shortcut 同一套人用参数:独立 user-data-dir 保存登录态
|
||||
cmd = [browser_exe, *human_chrome_launch_args(profile_abs, url)]
|
||||
# 有可恢复会话时不带 URL;首次/空 Profile 仍打开平台首页便于登录
|
||||
session_dir = os.path.join(profile_abs, "Default")
|
||||
has_session = any(
|
||||
os.path.isfile(os.path.join(session_dir, name))
|
||||
for name in ("Current Session", "Last Session", "Current Tabs", "Last Tabs")
|
||||
)
|
||||
launch_url = None if has_session else url
|
||||
cmd = [browser_exe, *human_chrome_launch_args(profile_abs, launch_url)]
|
||||
|
||||
log.info(
|
||||
"browser_open_launch exe=%s profile_dir=%s url=%s platform=%s restore_on_startup=%s",
|
||||
"browser_open_launch exe=%s profile_dir=%s launch_url=%s has_session=%s "
|
||||
"platform=%s restore_on_startup=%s",
|
||||
browser_exe,
|
||||
profile_abs,
|
||||
url,
|
||||
launch_url or "(restore)",
|
||||
has_session,
|
||||
target.get("platform_key"),
|
||||
prefs_result.get("restore_after"),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user