Files
cmshoppe/docs/tasks/T-561.md
T

53 lines
3.7 KiB
Markdown
Raw Normal View History

2026-07-08 17:47:50 +08:00
---
id: T-561
title: cmhub curl 下载隐藏 Windows 黑窗
phase: 7
deps: [T-548, T-524]
2026-07-08 17:49:54 +08:00
status: DONE
2026-07-08 17:47:50 +08:00
created: 2026-07-08
---
## 问题 / 背景
T-548 后,②AI生成在 Windows 下默认优先调用系统 `curl.exe` 下载 cmhub 返回的 `image_url`,用于绕过系统代理并提升图片下载速度。实际打包运行时,用户看到每次 curl 下载图片都会弹出黑色控制台窗口,持续几秒后消失。
根因:`app/ai.py` 的 `_download_cmhub_image_with_curl()` 使用 `subprocess.run([...], shell=False)` 启动系统 `curl.exe`,并已把 `stdout/stderr` pipe 住,但没有设置 Windows 隐藏窗口参数。打包后的 PySide6 程序是 GUI 进程,从 GUI 进程启动控制台程序 `curl.exe` 时,Windows 会为子进程创建可见控制台窗口;下载耗时几秒,黑窗就停留几秒。
## 方案
1. **只隐藏 curl 子进程窗口**
- 在 `app/ai.py` 增加 Windows 专用 helper,例如 `_subprocess_hidden_window_kwargs()`。
- 当 `os.name == "nt"` 时,优先给 `subprocess.run()` 传 `creationflags=subprocess.CREATE_NO_WINDOW`。
- 如需兼容环境没有该常量,兜底使用 `subprocess.STARTUPINFO()` + `STARTF_USESHOWWINDOW` + `SW_HIDE`。
- 非 Windows 返回空 dict,保持原逻辑。
2. **保持安全和下载语义不变**
- 仍使用 `shell=False`。
- 仍通过 `-K <临时配置文件>` 传 URL,避免 `image_url` 出现在进程命令行。
- 仍保留 `--silent`、`--show-error`、`--noproxy "*"`、超时、大小上限和失败回退 requests。
- 不把完整 URL、token、API Key 写入日志。
3. **测试**
- 更新 `tests/test_ai.py`,覆盖 Windows 分支下 `subprocess.run()` 收到隐藏窗口参数。
- 保留现有 curl 参数测试:URL 不在 argv、`shell=False`、`--noproxy`、超时、大小上限。
- 非 Windows 分支不强加隐藏窗口参数,避免影响 CI/Linux/macOS。
## 验收要点
- 打包版 ②AI生成用 curl 下载 cmhub 图片时,不再弹出黑色控制台窗口。
- curl 下载仍优先使用系统 curl,失败仍可回退 requests。
- `image_url` 仍不出现在 `subprocess.run()` 的 argv 中。
- 不改 cmhub 生文/生图 API、下载并发、DB、Excel、Shopee/CDP。
- `python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`py -3.10 -m unittest discover -s tests`、`git diff --check` 通过。
## 边界(不改什么)
只改 `app/ai.py` 的 curl 子进程启动参数和对应测试;不改 `ai.cmhub.download_with_curl` 配置 schema、不改系统 curl 检测、不改 requests fallback、不改图片保存 JPEG 逻辑、不改 GUI、DB、Excel、Shopee/CDP。
## 执行记录
2026-07-08 17:49:54 +08:00
- 2026-07-08:`app/ai.py` 新增 `_subprocess_hidden_window_kwargs()`,Windows 下优先使用 `subprocess.CREATE_NO_WINDOW` 隐藏 curl 子进程控制台窗口;缺少该常量时兜底 `STARTUPINFO + STARTF_USESHOWWINDOW + SW_HIDE`;非 Windows 返回空参数。
- 2026-07-08:`_download_cmhub_image_with_curl()` 调用 `subprocess.run()` 时传入隐藏窗口 kwargs,保留 `shell=False`、`-K` 临时配置文件、`--noproxy`、超时、大小上限、stderr/stdout 捕获和 requests fallback 语义。
- 2026-07-08:更新 `tests/test_ai.py`,覆盖 Windows curl 调用携带隐藏窗口参数、URL 不在 argv、`shell=False` 保持,以及非 Windows 不加隐藏窗口参数。
- 验证通过:`py -3.10 -m unittest tests.test_ai.AITests.test_cmhub_image_download_uses_curl_without_url_in_argv tests.test_ai.AITests.test_cmhub_curl_hidden_window_kwargs_are_windows_only tests.test_ai.AITests.test_cmhub_image_download_falls_back_to_requests_when_curl_fails tests.test_ai.AITests.test_cmhub_image_download_auto_without_curl_uses_requests`、`python -m ruff check app tests main.py`。