Release v2.0.1: create Chrome shortcut in profile dir on add-web
All checks were successful
技能自动化发布 / release (push) Successful in 5s

This commit is contained in:
2026-07-07 16:22:59 +08:00
parent 71bef19514
commit 549869b2bb
5 changed files with 189 additions and 9 deletions

View File

@@ -38,6 +38,7 @@ from service.secret_store import (
)
from util.logging_config import get_skill_logger
from util.platforms import get_platform_spec, seed_platforms
from util.profile_shortcut import create_profile_browser_shortcut
from util.runtime_paths import get_default_profile_dir_for_web
@@ -160,8 +161,10 @@ def cmd_account_add_web(
finally:
conn.close()
shortcut_path = create_profile_browser_shortcut(resolved_profile_dir, safe_label, log)
log.info("account_add_web_success id=%s platform=%s profile_dir=%s", new_id, key, resolved_profile_dir)
_say(_ok_json({
ok_payload = {
"id": new_id,
"platform_key": key,
"account_label": safe_label,
@@ -176,7 +179,10 @@ def cmd_account_add_web(
"auth_strategy": resolved_auth,
"session_persistent": sp,
"device_fingerprint": device_fingerprint,
}))
}
if shortcut_path:
ok_payload["profile_shortcut"] = shortcut_path
_say(_ok_json(ok_payload))
def cmd_account_add_secret(

View File

@@ -33,13 +33,12 @@ def _win_find_exe(candidates):
return None
def resolve_chromium_channel():
def resolve_chromium_executable():
"""
Playwright channel: 'chrome' | 'msedge' | None
Windows 优先 Chrome其次 Edge其它系统默认 chrome由 Playwright 解析 PATH
Windows 上返回 chrome.exe 或 msedge.exe 的绝对路径;未找到或非 Windows 返回 None
"""
if sys.platform != "win32":
return "chrome"
return None
pf = os.environ.get("ProgramFiles", r"C:\Program Files")
pfx86 = os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)")
@@ -53,7 +52,7 @@ def resolve_chromium_channel():
]
)
if chrome:
return "chrome"
return chrome
edge = _win_find_exe(
[
@@ -63,11 +62,27 @@ def resolve_chromium_channel():
]
)
if edge:
return "msedge"
return edge
return None
def resolve_chromium_channel():
"""
Playwright channel: 'chrome' | 'msedge' | None
Windows 优先 Chrome其次 Edge其它系统默认 chrome由 Playwright 解析 PATH
"""
if sys.platform != "win32":
return "chrome"
exe = resolve_chromium_executable()
if not exe:
return None
if os.path.basename(exe).lower() == "msedge.exe":
return "msedge"
return "chrome"
def _print_browser_install_hint():
print("❌ 未检测到 Google Chrome 或 Microsoft Edge请先安装")
print(" • Chrome: https://www.google.com/chrome/")

View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
"""在 Profile 目录内创建浏览器快捷方式Windows .lnk"""
from __future__ import annotations
import logging
import os
import re
import subprocess
import sys
from typing import Optional
from service.browser_service import resolve_chromium_executable
_WIN_LNK_FORBIDDEN = re.compile(r'[<>:"/\\|?*\x00-\x1f]')
def _lnk_safe_filename(name: str, fallback: str = "browser") -> str:
t = _WIN_LNK_FORBIDDEN.sub("_", (name or "").strip())
t = t.rstrip(" .")
return t or fallback
def _ps_single_quote(value: str) -> str:
return "'" + value.replace("'", "''") + "'"
def create_profile_browser_shortcut(
profile_dir: str,
account_label: str,
log: Optional[logging.Logger] = None,
) -> Optional[str]:
"""
在 profile_dir 内创建 {account_label}.lnk目标为系统 Chrome/Edge + --user-data-dir。
非 Windows 或未安装 Chrome/Edge 时静默跳过,返回 None。
成功返回 .lnk 绝对路径。
"""
if log is None:
log = logging.getLogger(__name__)
if sys.platform != "win32":
log.debug("profile_shortcut_skip platform=%s", sys.platform)
return None
browser_exe = resolve_chromium_executable()
if not browser_exe:
log.warning("profile_shortcut_skip reason=no_chromium")
return None
profile_abs = os.path.abspath(profile_dir)
os.makedirs(profile_abs, exist_ok=True)
lnk_name = f"{_lnk_safe_filename(account_label)}.lnk"
lnk_path = os.path.join(profile_abs, lnk_name)
arguments = f'--user-data-dir="{profile_abs}"'
working_dir = os.path.dirname(browser_exe)
ps = (
"$WshShell = New-Object -ComObject WScript.Shell; "
f"$s = $WshShell.CreateShortcut({_ps_single_quote(lnk_path)}); "
f"$s.TargetPath = {_ps_single_quote(browser_exe)}; "
f"$s.Arguments = {_ps_single_quote(arguments)}; "
f"$s.IconLocation = {_ps_single_quote(browser_exe + ',0')}; "
f"$s.WorkingDirectory = {_ps_single_quote(working_dir)}; "
"$s.Save()"
)
try:
subprocess.run(
["powershell", "-NoProfile", "-NonInteractive", "-Command", ps],
check=True,
capture_output=True,
text=True,
)
except (OSError, subprocess.CalledProcessError) as exc:
log.warning("profile_shortcut_failed profile_dir=%s error=%s", profile_abs, exc)
return None
if not os.path.isfile(lnk_path):
log.warning("profile_shortcut_missing_after_create path=%s", lnk_path)
return None
log.info("profile_shortcut_created path=%s browser=%s", lnk_path, browser_exe)
return lnk_path