fix(m196): GUI 产物 PE Subsystem → WINDOWS_GUI(2),并用 AttachConsole 保住 CLI 输出

群友 2026-11-08 实测发布构建「运行时会带一个控制台窗口在底下」。根因:产物 PE 头
Subsystem 仍是 CUI(3)。同一个修复 2026-11-01 做过一次(37d3039),但只改了已被
workspace exclude 的 Slint 树(crates/app),从未到达 iced 产物。

- crates/app-iced/src/main.rs:加 #![cfg_attr(windows, windows_subsystem = "windows")],
  并写清为什么放 bin 层而不是 build.rs(PE 子系统是每个 bin 目标的属性)。
- crates/app-iced/src/platform/win32/console.rs(新):AttachConsole(ATTACH_PARENT_PROCESS)
  的落点 + 判据 should_attach(纯函数,可断言)。GUI 子系统进程不继承父控制台,实测
  从 cmd 启动时三个 std 句柄全是 0;附着后 GetStdHandle 立刻给出控制台句柄(0x0→0x208),
  所以不改 std 句柄、不碰用户的重定向(ATTACH_PARENT_PROCESS 只会附到已存在的控制台,
  永不新建窗口)。
- packaging/check_pe_subsystem.py(新):读产物 PE 头 Subsystem 字段(GUI 必须 2、
  CLI ull 必须 3),非 2 即红;--self-test 注入 5 条合成 PE 回归。
- 接进 release-build.yml(发布侧两槽位)与 ci.yml build job(PR 阶段)。
- guards.yml:unsafe 落点期望集合变成两处(console.rs + transparency.rs),集合相等判据其余不变;
  平台层所有「全仓唯一 unsafe 落点」措辞同步改正。
This commit is contained in:
tower-worker committed 2026-11-08 19:33:56 +08:00
1 parent 30b61e2684
commit 14f9318e09
15 files changed
+693 -36

No files matched your search

+20
View File
@@ -259,6 +259,26 @@ jobs:
echo "::error::静态 CRT 未生效:exe 仍动态依赖 VC++ 可再发行包"; exit 1
fi
# M196:**读产物 PE 头的 `Subsystem`**,不读源码。同一个修复 2026-11-01 曾打在已退役的 Slint 树
# (`37d3039` 只改了 `crates/app/src/main.rs`,而 `crates/app` 自 M118 起被 workspace `exclude`、
# 不进发布矩阵),于是「代码里写过」与「产物里有没有」彻底脱钩——双击多一个控制台窗口这个 bug
# 就是这么活到 2026-11-08 的。本步只认那 4 个字节:GUI 产物必须是 WINDOWS_GUI(2),非 2 即红。
# 反方向一并守:CLI 产物 `ull.exe` 必须仍是 CONSOLE(3)——它靠真控制台做 stdout/stderr,
# 谁把属性抄到它头上,`ull --version | …` 会静默丢输出。守门本体在 packaging/check_pe_subsystem.py
# (零第三方依赖,本地同一份代码可跑;`--self-test` 注入 5 条回归证明它会红)。
- name: PE 子系统门禁(GUI 产物必须 WINDOWS_GUI/2,CLI 产物必须 CONSOLE/3)
if: runner.os == 'Windows'
shell: bash
env:
BUILD_DIR: ${{ inputs.build_dir }}
run: |
set -euo pipefail
PY=$(command -v python3 || command -v python)
# 读数(含文件字节偏移)直接进日志:红的时候要看的就是这个数,而不是「脚本说不对」。
"$PY" packaging/check_pe_subsystem.py \
--gui "$BUILD_DIR/unlucky-launcher-iced.exe" \
--cli "$BUILD_DIR/ull.exe"
- name: 打包(产物 + SHA256SUMS)
shell: bash
env: