Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/I18N.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ sudo meson install
| 新增含 `_()` 的源文件 | 将路径添加到 `POTFILES` → 重新生成 `.pot` → 合并 → 翻译 |
| 新增 `.blp` 文件中的字符串 | 先编译 Blueprint → 重新生成 `.pot` → 合并 → 翻译 |
| 新增界面语言 | 在 `LINGUAS` 添加语言代码 → 创建 `.po` → 在 `meson.build` 的 `languages` 数组添加 → 翻译 |
| 临时切换运行语言 | 使用 `LANGUAGE=en filecollector` 环境变量,对 GUI 和 CLI 均生效 |
| 临时切换运行语言 | Linux/macOS:`LANGUAGE=en filecollector`,对 GUI 和 CLI 均生效;**Windows 下 `LANGUAGE` 会被 gettext 忽略**(无 `LANG`/`LC_*` 变量时 locale 落回 "C",这是 GNU gettext 的既定行为),须改用 `LANG=zh_CN.UTF-8 filecollector` 或 `LANG=en filecollector` |

---

Expand Down
60 changes: 60 additions & 0 deletions src/main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,70 @@ public class FileCollectorApp : Adw.Application {
var lang_setting = FileCollectorWindow.load_settings_language ();
if (lang_setting == "en") {
GLib.Environment.set_variable ("LANGUAGE", "en", true);
#if WINDOWS
// Windows 的 gettext 只在当前 locale 非 "C" 时才读取 LANGUAGE
// (GNU gettext 的既定行为); 而此环境在无 LANG/LC_* 变量时 locale
// 落回 "C", LANGUAGE 被整体忽略 -> 语言设置永远只有英文。
// 实测须同时设 LANG 让 locale 脱离 "C":
// 仅 LANGUAGE=zh_CN -> 英文
// LANGUAGE=zh_CN + LANG=zh_CN.UTF-8 -> 中文
// zh 用 "zh_CN.UTF-8" 是为了与 locale/ 下的目录名一致 (gettext
// 按 LANG 值逐级尝试 zh_CN -> zh 查找 .mo), 且 UCRT 可解析。
GLib.Environment.set_variable ("LANG", "en", true);
GLib.Environment.set_variable ("FILECOLLECTOR_LANG_MANAGED", "1", true);
#endif
} else if (lang_setting == "zh") {
GLib.Environment.set_variable ("LANGUAGE", "zh_CN", true);
#if WINDOWS
GLib.Environment.set_variable ("LANG", "zh_CN.UTF-8", true);
GLib.Environment.set_variable ("FILECOLLECTOR_LANG_MANAGED", "1", true);
#endif
} else {
GLib.Environment.unset_variable ("LANGUAGE");
#if WINDOWS
// 跟随系统: 此 gettext 构建在没有 LANG/LC_* 变量时拿不到 Windows
// 的用户语言 (locale 落回 "C" -> 英文, 见上方注释), 因此把 Windows
// 用户 locale 翻成 Unix 风格名字 (zh-CN -> "zh_CN") 喂给 LANG。
//
// g_win32_getlocale() 的实现是: 有 LANG/LC_* 环境变量时原样返回
// 其值, 只有全空才查 Windows (GetThreadLocale)。重启子进程总带着
// 上一会话写入的 LANG (拼 .UTF-8 会得到垃圾值), Git Bash 还会塞
// LANG=C.UTF-8 —— 所以先临时摘掉这三个变量, 强制走 Win32 路径。
//
// FILECOLLECTOR_LANG_MANAGED 标记 LANG 是否由本应用写入:
// - 有标记 (重启链路) -> 无条件覆盖, 保证 zh/en 切回"跟随系统"
// 时不会残留旧语言;
// - 无标记但 LANG 是 "C"/"C.*"/"POSIX" (Git Bash 默认, 不表达
// 语言偏好) -> 视同未设置, 覆盖为系统 locale;
// - 无标记且 LANG 有真实语言 (用户在 shell 里故意设的) -> 尊重。
bool lang_is_ours = GLib.Environment.get_variable ("FILECOLLECTOR_LANG_MANAGED") != null;
string inherited = GLib.Environment.get_variable ("LANG") ?? "";
bool lang_is_c = inherited == "C" || inherited.has_prefix ("C.") || inherited == "POSIX";
if (lang_is_ours || inherited.length == 0 || lang_is_c) {
string? saved_lc_all = GLib.Environment.get_variable ("LC_ALL");
string? saved_lc_msg = GLib.Environment.get_variable ("LC_MESSAGES");
string? saved_lang = GLib.Environment.get_variable ("LANG");
GLib.Environment.unset_variable ("LC_ALL");
GLib.Environment.unset_variable ("LC_MESSAGES");
GLib.Environment.unset_variable ("LANG");
var sys_locale = GLib.Win32.getlocale ();
if (saved_lc_all != null) {
GLib.Environment.set_variable ("LC_ALL", saved_lc_all, true);
}
if (saved_lc_msg != null) {
GLib.Environment.set_variable ("LC_MESSAGES", saved_lc_msg, true);
}
if (saved_lang != null) {
GLib.Environment.set_variable ("LANG", saved_lang, true);
}
if (sys_locale != null && sys_locale.length > 0 && !sys_locale.has_prefix ("C")) {
GLib.Environment.set_variable ("LANG", sys_locale + ".UTF-8", true);
GLib.Environment.set_variable ("FILECOLLECTOR_LANG_MANAGED", "1", true);
} else {
GLib.Environment.unset_variable ("LANG");
}
}
#endif
}

Intl.setlocale (LocaleCategory.ALL, "");
Expand Down
12 changes: 12 additions & 0 deletions tools/build-windows-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ BAT
# 打包前用 PE 导入表做依赖闭包校验, 任何一个非系统 DLL 缺失都直接失败。
python3 tools/verify_windows_package.py "${STAGING_DIR}"

# i18n 运行时冒烟: --help 走完整 gettext 链 (bindtextdomain -> zh_CN.mo 加载)。
# 曾出过: .mo 在包里、清单校验也过, 但 gettext 运行时根本没加载译文, 语言
# 设置/跟随系统在用户侧永远只有英文 (Windows 下 gettext 在 locale 为 "C" 时
# 忽略 LANGUAGE)。这里真实运行主程序验证译文可达, 而不是只看清单。
echo "Running i18n runtime smoke test (LANG=zh_CN.UTF-8 --help -> Chinese) ..."
HELP_OUT="$(cd "${STAGING_DIR}/bin" && LANG=zh_CN.UTF-8 ./filecollector.exe --help 2>/dev/null || true)"
if ! printf '%s\n' "${HELP_OUT}" | grep -q '命令行模式'; then
echo "i18n smoke test failed: --help output is not Chinese with LANG=zh_CN.UTF-8" >&2
printf '%s\n' "${HELP_OUT}" | head -5 >&2
exit 1
fi

PACKAGE_PATH="${DIST_DIR}/filecollector-windows-${VERSION}-x64.zip"
(
cd "${STAGING_DIR}"
Expand Down
Loading