# FrpGUI **Repository Path**: minivip/frp-gui ## Basic Information - **Project Name**: FrpGUI - **Description**: FrpGUI:基于 Go+Shirei(IMGUI) 的跨平台 frpc 桌面图形前端,单二进制、低依赖,支持完整 frpc 配置、多语言与多主题。 FrpGUI: cross-platform frpc desktop GUI in Go + Shirei (IMGUI). Single binary, low deps; full frpc config, i18n & theming. - **Primary Language**: Go - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2026-10-20 - **Last Updated**: 2026-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FrpGUI > frpc(frp 内网穿透客户端)的跨平台图形化管理工具。轻量、原生、零依赖,让你不必手改配置文件或用命令行,就能轻松配置和管理内网穿透。 ![平台](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-blue) ![许可证](https://img.shields.io/badge/license-MIT-green) ![语言](https://img.shields.io/badge/UI-Go%20%2B%20Shirei-orange) - **作者**:Mirai - **开源协议**:MIT License — FrpGUI 自身代码以 MIT 发布;所引用的框架与第三方组件均按其各自许可证合规使用,并随附归因(详见 [THIRD-PARTY-LICENSES.md](THIRD-PARTY-LICENSES.md)) - **上游项目**:[frp (fatedier/frp)](https://github.com/fatedier/frp) · 官方文档 - **版本**:v1.0 - **项目地址**: - Gitee: - GitHub: --- ## 背景与初衷 FrpGUI 立项于 2026-08-13(作者 Mirai,MIT 协议),是 frp 生态中的第三方图形化客户端。 其初衷来自一份早期需求文档,核心要点如下: - **目标人群与价值**:让非技术用户也能轻松配置与管理内网穿透,不必手改 `frpc.toml` 或敲命令行。 - **产品设计原则**:跨平台原生、轻量、零依赖——交付单一原生二进制(无 GTK/Qt 等运行时,体积约 10MB 量级),下载后双击即跑。 - **技术选型依据**:采用 Go + Shirei(纯 Go、无 CGO、即时模式 IMGUI,对 AI 辅助开发友好),与 frp 核心技术栈一致、便于长期维护。 - **部署形态**:主程序 + 独立 `frpc` 二进制,通过 `os/exec` 调用外部 frpc 实现穿透,frpc 由用户从官方 Releases 下载随附(不内置、不打包源码)。 - **协作方式**:项目以「与 AI 对话迭代开发」为主要模式,因此代码保持清晰、模块化,并在关键逻辑处保留中文注释。 > 上述初衷提炼自项目早期的立项需求文档;该文档已完成其历史使命,相关精神已并入本 README 与开发文档。 --- ## 功能特性 - **跨平台原生程序**:Windows / macOS / Linux 均以原生二进制运行,界面风格自然。 - **单一二进制、零依赖**:无 GTK / Qt 等运行时;最终产物体积小(约 10MB 量级)。 - **配置管理**:图形化创建、编辑、加载 `frpc.toml` 配置(改动自动保存,无需手动保存;服务端地址、端口、Token、代理规则增删改)。 - **进程控制**:通过「启动 / 停止」按钮管理后台 frpc 子进程的生命周期。 - **运行状态与日志**:清晰显示「已停止 / 运行中 / 启动失败 / 连接失败」等状态,并实时滚动展示 frpc 运行日志(支持一键复制)。 - **导入 / 导出配置**:通过文件对话框导入或导出 `frpc.toml`。 - **系统托盘(Windows)**:关闭按钮最小化到托盘;单击 / 双击托盘图标恢复窗口;右键菜单含「主界面 / 启动 / 停止 / 退出」。 - **多语言**:内置 16 种语言(简体中文 / 繁體中文 / 英文 / 日文 / 韩文 / 西班牙文 / 意大利文 / 俄文 / 法文 / 德文 / 葡萄牙文 / 阿拉伯文 / 越南文 / 印尼文 / 泰文 / 土耳其文),语言包「放文件即生效」,可在「语言」菜单中热切换。 - **字体选择**:动态枚举系统全部字体,可一键恢复「系统默认」。 - **主题配色**:单一主题维度。内置仅「简约」(浅色默认)与「深色 Dark」两套保底(永不消失,删光主题文件也不会没主题用);其余彩色主题(蓝 / 绿 / 粉 / 橙 / 咖啡 / 薄荷)均为 `theme/*.toml` 文件扩展,随仓库提供范例、可删可自制。顶部「主题」菜单热切换并持久化。 - **顶部标签页**:固定顶部标签栏切换「服务端 / 代理 / 工具 / 日志」四个主功能区,点击即时切换;上方控制条(状态 / 启停 / 已加载预设 / 导入导出)常驻,宽度随窗口自适应并按标签页钳制表单列宽。 --- ## 下载与运行 1. 从 [Releases](../../releases) 下载对应平台的可执行文件(或自行从源码构建,见下)。 2. 把官方 frp 的 **`frpc`(`frpc.exe`)** 放到 FrpGUI 可执行文件**同目录**(或确保其在 `PATH` 中)。 - frpc 下载地址: 3. 双击 `FrpGUI`(`FrpGUI.exe`)启动即可。 > UI 默认语言按操作系统区域推断(中文环境默认简体中文,否则英文);用户偏好(语言、字体)持久化在程序同目录的 `settings.json`。 --- ## 界面截图 > 以下截图基于 Windows 平台,展示 FrpGUI 的主要界面。 ### 服务端配置 ![服务端配置界面](docs/imgs/服务端配置界面.png) ### 代理配置 ![代理配置界面](docs/imgs/代理配置界面.png) ### 工具页 ![工具界面](docs/imgs/工具界面.png) ### 日志页 ![日志界面](docs/imgs/日志界面.png) ### 主题配色选择 ![主题配色选择](docs/imgs/主题配色选择.png) ### 字体选择 ![字体选择界面](docs/imgs/字体选择界面.png) ### 语言选择 ![语言选择](docs/imgs/语言选择.png) --- ## 从源码构建 需要 Go 1.25 或更高(本项目以 Go 1.26.5 验证)。 ```bash # 仓库根目录执行 go mod tidy # Windows(GUI 子系统,无控制台黑框) go build -ldflags="-s -w -H windowsgui" -o FrpGUI.exe ./cmd/frpguiapp # macOS / Linux go build -ldflags="-s -w" -o FrpGUI ./cmd/frpguiapp ``` 构建产物为单一二进制 `FrpGUI`(或 `FrpGUI.exe`)。 > 推荐使用仓库自带的跨平台构建助手(自动设置 CGO / `-H windowsgui` / 按平台命名): > `go run ./tools [windows|linux|darwin]`。产物统一输出到 **`build/<平台>-amd64/`** 子目录 > (如 `build/windows-amd64/FrpGUI.exe`、`build/linux-amd64/FrpGUI`),按平台区分且被 > `.gitignore` 的 `build/` 规则忽略,不会污染仓库根目录、也不会误提交。构建助手还会顺带把 > `lang/`、`theme/`、`frpc.example.toml` 等运行时资产复制到产物目录,因此 `build/<平台>-amd64/` > 是一个可直接运行的完整包(应用按 exe 同级查找语言包与主题,无需再从仓库根启动)。上面的手动 > `go build -o` 则按你指定的 `-o` 路径输出(多为仓库根),需自行把 `lang/`、`theme/` 放到 exe 同级。 --- ## 参与开发与治理 / Development & Governance - [贡献指南 CONTRIBUTING.md](CONTRIBUTING.md):环境要求、本地构建、质量门禁、代码风格、语言包/主题扩展、PR 流程。 - [架构与设计契约 ARCHITECTURE.md](docs/ARCHITECTURE.md):模块布局、`cfg` 并发安全契约、序列化契约、i18n/主题机制。 - [安全政策 SECURITY.md](SECURITY.md):受支持版本、漏洞披露渠道、供应链与签名、用户数据处理。 - [发布流程 RELEASE.md](docs/RELEASE.md):语义化版本、打标签、跨平台构建、签名与校验和。 > 以上文档均提供英文版(文件名加 `_EN` 后缀,例如 `docs/ARCHITECTURE_EN.md`、`CONTRIBUTING_EN.md`、`SECURITY_EN.md`、`docs/RELEASE_EN.md`)。 本地一键复现 CI 门禁:`make ci`(gofmt 检查 + `go vet` + `go test -race` + 跨平台构建)。 --- ## 使用说明 ### 配置 frpc 程序的服务器配置与代理规则都对应标准 `frpc.toml` 格式。你可以: - 在界面里直接填写「服务端地址 / 端口 / Token」并「新增代理」; - 所有修改会**自动保存**到 `frpc.toml`(无需点击保存按钮); - 或用「导入配置 / 导出配置」在文件间搬运。 首次启动若找不到 `frpc.toml`,会载入默认空配置(界面顶部显示「已加载:默认配置」)。可参考仓库内的 `frpc.example.toml` 模板。 ### 导入 / 导出配置 - **导出**:把当前配置「另存为」一个 `frpc.toml` 文件到任意位置;导出**不会改变**当前已加载的预设(不会切换档案)。 - **导入**:先解析目标文件。解析失败会弹窗提示错误;解析成功则在 `profiles/` 下创建**同名**预设(`profiles/<文件名>.toml`): - frpc **正在运行**:弹窗提示「导入成功」,并询问是否**停止并切换到**新导入的配置;可取消,取消后新配置仍保留在 `profiles/` 供后续手动切换。 - frpc **未运行**:直接切换并弹窗提示「导入成功」。 ### 启动 / 停止 点击「启动」会通过 `os/exec` 拉起同目录(或 PATH 中)的 `frpc` 子进程,并实时捕获其 stdout/stderr 日志到界面日志区;「停止」按 PID 精确终止该子进程。**程序只管理自己启动的 frpc,不会误杀你机器上其它正在运行的 frpc。** ### 开机自启(工具页) 「工具」页提供「开机自启」开关:启用后登录系统时自动启动(Windows 写注册表 `Run` 键、Linux 写 `~/.config/autostart` 的 `.desktop`、macOS 写 `~/Library/LaunchAgents` 的 plist)。 - 开关状态**不写入** `settings.json`,而是实时读取操作系统自身的开机项——真相源就是系统,程序退出 / 重装 / 换盘后状态依然正确,也不会出现「JSON 说已启用、系统实际未启用」的漂移。 - 工具页实时显示当前状态(启用 / 禁用),点击「启用 / 禁用」立即生效。 --- ## 系统托盘行为(Windows) 关闭按钮的行为取决于 frpc 运行状态: - **运行中**:点击右上角关闭按钮 → 最小化到托盘(不直接退出程序),可从托盘恢复。 - **未运行**:点击关闭按钮 → 直接退出程序。 托盘交互: - 单击 / 双击托盘图标 → 恢复主窗口 - 右键托盘图标 → 菜单:主界面 / 启动 / 停止 / 退出 - 「退出」会干净地停止 frpc、移除托盘图标并关闭程序 - **防误触**:frpc 运行中时,从菜单切换预设、或在托盘菜单选择「退出」这类「会导致 frpc 关闭、连接断开」的操作,会先弹出确认框警告「将断开连接」并询问是否继续;非运行中则直接执行。 > macOS / Linux 暂未实现托盘,关闭按钮行为保持系统默认(直接关闭窗口)。 --- ## 日志系统 程序内置一套异步文件日志,便于排查问题,且不影响主程序性能: - **分级**:`DEBUG < INFO < WARN < ERROR`,默认级别 `INFO`。级别写在 `settings.json` 的 `log_level` 字段,修改后重启生效。 - **非阻塞**:所有日志经带缓冲的 channel 派发到后台 goroutine 写入,调用方永不阻塞(通道极端满载时丢弃并计数,避免拖慢主程序)。 - **按月分目录、按天分文件**:`logs//app-.log` 与 `logs//frpc-.log`,跨零点自动新建当日文件、跨月自动新建当月目录。 - **两个日志文件**: - `app-.log` —— 程序自身运行日志(自检、配置加载、启动/停止、导入导出、错误等),受 `log_level` 过滤。 - `frpc-.log` —— frpc 子进程的 stdout/stderr 原始输出,**始终记录**(frpc 自身已带级别,不做过滤)。 - **目录位置**: - Windows:程序所在目录的 `logs/`(便携,随程序同目录)。 - macOS / Linux:遵循 XDG 规范,位于用户缓存目录 `~/Library/Caches/FrpGUI/logs`(macOS)或 `$XDG_CACHE_HOME/FrpGUI/logs`(Linux)。 - GUI 内的实时日志面板照常显示,与文件日志相互独立、互不影响。 - **界面日志面板**:单一统一缓冲把程序自身日志与 frpc 子进程输出**按到达顺序混合**显示——无需每帧重算、也无跨天排序问题。GUI 行带 `HH:MM:SS` 前缀,frpc 行保留 `HH:MM:SS.mmm`(已去除 ANSI、去掉日期)。界面仅保留**最近 1000 条**,更早的完整带日期历史在上面的文件里。复制选中(或全部)行写入剪贴板后,会在「复制」按钮旁显示一条带 `HH:MM:SS` 前缀的「已复制」瞬时提示,3 秒后自动消失(连续复制会刷新时间戳)。 --- ## 多语言与字体 - 新增语言:复制 `lang/zh-CN.toml` 为 `lang/<语言码>.toml`,翻译右侧值并在文件内设置 `lang_name`,无需改代码,「语言」菜单会自动列出。 - **内置保底语言(3 套,永不消失)**:`zh-CN`(简体中文)、`zh-TW`(繁體中文)、`en`(English) 经 `go:embed` 编译进二进制(见 `lang_builtin.go`),即便用户删光了所有 `lang/*.toml`, 也始终可选可用、不会出现「没有语言可选」的窘境。磁盘上若存在同名 `.toml`,则覆盖 内置版本(同名则覆盖),与主题的内置/文件关系一致。其余 13 种语言仍为纯文件扩展(删了即从菜单消失)。 - **语言菜单顺序**:固定把 `zh-CN` → `zh-TW` → `en` 排在菜单最前,其余语言(内嵌或磁盘)统一按字母升序跟在后面,顺序稳定、便于查找。 - **默认启用语言**:优先使用用户已持久化的选择;若无,则按操作系统界面语言(`detectOSLang` 依次看 `LC_ALL`/`LC_MESSAGES`/`LANG` 与 Windows `GetUserPreferredUILanguages`)推断,命中可用语言包即用;**都未命中则默认回退英文(`en`)兜底**,保证初次启动总有可读界面。 - 字体在「字体」菜单中动态枚举系统字体选择,可随时恢复「系统默认」。 ### 字体策略:不内置任何字体 FrpGUI **不打包、不内嵌**任何字体文件(包括 Noto Sans 等),以守住「单一二进制、零依赖、体积小」的初衷。 - **为什么不内嵌**:实测表明 `go:embed` 对 TTF 几乎不压缩——嵌入本机 17.7MB 的 Noto Sans SC,二进制仅增约 17MB(压缩比 1.001),即「实付 ≈ 字体文件大小」。要内嵌整族 Noto 覆盖 800+ 语种需数百 MB,得不偿失。详细实测见[开发踩坑文档 §21](docs/DEVELOPMENT_PITFALLS.md#21-字体不内嵌goembed-对-ttf-几乎不压缩字体嵌入体积实测)。 - **程序怎么取字形**:通过 Shirei 的字体子系统 + 应用层「字体回退链」自动回退——已枚举 16 个覆盖字体(Nirmala UI / Leelawadee UI / Microsoft JhengHei / Yu Gothic UI / Nyala / Ebrima 等),把系统已安装的字体作为兜底,零体积代价。 - **冷门语种显示不出来怎么办**:若某语言(如韩文、泰文、阿拉伯文、天城文等)出现方块或空白,说明你的系统缺少对应字形字体。**请自行在操作系统安装相应字体**(Windows:设置 → 字体,或从 Microsoft Store 安装 *Noto Sans* 系列、或系统自带的韩文/泰文/阿拉伯字体;Linux/macOS 同理),**安装后重启 FrpGUI(或点「字体」菜单里的刷新)即可自动识别并回退显示**。无需修改程序、无需重编译。 ## 主题配色 配色按「语义角色」集中管理,只有一个维度——**主题(theme)**,均「放文件即生效」,无需改代码。 - **内置保底主题(2 套,永不消失)**:`minimal`(简约,浅色默认,马卡龙中性灰 + 黑字)、`dark` (深色 Dark,低亮度背景 + 白色文字,即「简约」的中性灰暗色版)。二者硬编码在程序中, 即便用户删光了所有 `theme/*.toml`,也始终可用,不会出现「没有主题可选」的窘境。 - **文件扩展主题(仓库自带范例,可删可改)**:`blue` / `green` / `pink` / `orange` / `coffee` / `mint` 等彩色主题,各自对应一份 `theme/.toml`,取色完全由文件里的 `hue`/`sat` 决定。 它们**不是内置**——删掉文件即从菜单消失,用户可照葫芦画瓢自制(复制一份改名改 `hue` 即可)。 - **切换主题**:顶部「主题」菜单先列出内置保底(简约置顶、深色紧随其后),再按字母序枚举 `theme/*.toml`,选择即热重载并持久化。 新增 / 自定义浅色主题:复制任意一份范例(如 `theme/blue.toml`)为 `theme/.toml`,只需声明主色相与饱和度即可—— ```toml theme_name = "示例 Example" # 菜单显示名 hue = 280 # 主色相 0-360(紫色) sat = 65 # 主饱和度 0-100 light_tint = 10 # 可选:浅色模式下交互色额外饱和度(马卡龙感) dark_tint = 20 # 可选:深色模式下交互色额外饱和度(更明艳;仅当该主题为深色时生效) dark_accent_l = 62 # 可选:深色模式强调色亮度 L(越高越亮) ``` 语义角色由程序按色相/饱和度自动派生(浅色主题用 `buildLight`,深色主题用 `buildDark`),无需逐字段手写。 `minimal` 与 `dark` 均为**纯内置**(无对应 toml 文件,删光 `theme/*.toml` 也始终可用);若想微调主题, 复制任意一份彩色范例(如 `theme/blue.toml`)改名改 `hue` 即可,或在 `theme/` 下放一份 `dark.toml` 覆盖 `dark_accent_l` 来微调深色主题的强调色亮度。 --- ## 项目结构 ``` FrpGUI/ ├── cmd/frpguiapp/ # 全部源码(package main,按职责拆分同包多文件) │ ├── main.go # 入口:偏好/语言/配置加载、窗口/图标/托盘初始化、退出清理 │ ├── state.go # 全局应用状态(统一日志缓冲、日志选区、复制提示、当前标签等) │ ├── panels.go # 主界面 RootView 与 服务端/代理/工具/日志 四个面板 │ ├── menu.go # 顶部菜单(档案/主题/字体/语言/帮助)与字体弹窗 │ ├── handlers.go # 按钮回调(启动/停止/导入导出/诊断) │ ├── widgets.go # 复用的小型 UI 控件 │ ├── config.go # frpc.toml 全字段读写(自定义 Marshal/Unmarshal) │ ├── prefs.go # settings.json 偏好持久化(语言/字体/日志级别/主题) │ ├── profiles.go # 多配置预设(profiles/.toml 管理) │ ├── clear_creds.go # 清除凭据入口(与脱敏白名单同步) │ ├── logger.go # 异步、分级、按月分目录按天分文件日志(app / frpc 两个日志器) │ ├── crash.go # 未捕获 panic 落盘崩溃日志 │ ├── diagnostics.go # 导出诊断信息(脱敏 settings + frpc + 日志打包) │ ├── process.go # frpc 子进程管理(通用 FrpcManager + 日志采集) │ ├── process_{windows,other}.go # 启动 frpc 的平台拆分 │ ├── stop_{windows,other}.go # 停止 frpc 的平台拆分(SIGTERM / 强杀回退) │ ├── integrity.go # frpc 二进制完整性校验(SHA256 比对基准) │ ├── netcheck.go # 后台连通性 / 延迟测试 │ ├── tray_windows.go # 系统托盘(Windows 实装,子类化 WM_CLOSE) │ ├── tray_{common,other}.go # 托盘公共逻辑 / 非 Windows 空实现 │ ├── single_instance_{windows,other}.go # 单实例锁(平台拆分) │ ├── startup_{windows,linux,darwin}.go # 开机自启(平台拆分) │ ├── theme.go # 主题(单一维度,hue+sat 派生 25 个语义角色) │ ├── lang.go # 语言包加载与动态枚举(文件优先,缺失回退内置) │ ├── lang_builtin.go # 内嵌兜底语言包(zh-CN/zh-TW/en,go:embed) │ ├── locale_{windows,other}.go # OS 语言推断(平台拆分) │ ├── filepicker.go # 自绘纯 Go 文件选择弹窗(替代 sqweek/dialog) │ ├── confirm.go # 通用确认弹窗 │ ├── icon/ # 图标源(icon.png 经 go:embed;Windows 资源 resource_windows.syso) │ └── *_test.go # 22 个测试文件(覆盖率门禁 go test -race;Go 要求与源码同目录,go build 自动忽略、不进二进制) ├── lang/ # 16 份语言包(zh-CN/zh-TW/en 亦内嵌进二进制作兜底 + 13 种其它语言) ├── theme/ # 6 份彩色主题(blue/coffee/green/mint/orange/pink);minimal/dark 为内置 ├── profiles/ # 多配置预设(运行期用户数据,含明文 Token,已被 .gitignore 排除,不入库) ├── tools/ # 构建与供应链工具:build.go(跨平台构建)、sbom.go(SBOM 生成) ├── docs/ # 架构/踩坑/发布/安全 文档(ARCHITECTURE/DEVELOPMENT_PITFALLS/RELEASE 均提供 _EN 英文版) ├── frp_*/ # 官方 frpc 解压目录(运行期放置 frpc 二进制;gitignored,不入库) ├── logs/ # 运行期日志(按月分目录;gitignored) ├── frpc.example.toml # 配置示例模板(可入库) ├── go.mod / go.sum ├── Makefile # ci / build / sbom / supply-chain 等目标 ├── README.md / README_EN.md / CONTRIBUTING.md / CONTRIBUTING_EN.md / SECURITY.md / SECURITY_EN.md └── .gitignore ``` > 注:运行期生成的 `frpc.toml`(默认配置)与构建产物 `FrpGUI(.exe)`、以及 `profiles/`、`frp_*/`、`logs/` 均被 `.gitignore` 排除,不入库;仓库内 `theme/` 仅含 6 份彩色范例,`minimal`/`dark` 为主题内置、无需文件。 --- ## 技术栈 - **语言**:Go - **GUI 框架**:[Shirei](https://pkg.go.dev/go.hasen.dev/shirei)(纯 Go、无 CGO、即时模式 IMGUI)——契合「单一二进制、零依赖」目标。 - **依赖**:`go.hasen.dev/shirei`(GUI)、`github.com/pelletier/go-toml/v2`(TOML 解析)、`golang.org/x/sys`(平台 API)。文件对话框为自绘纯 Go 实现(`filepicker.go`),无第三方对话框库;Windows/Linux 为 `CGO_ENABLED=0` 纯 Go 单二进制,macOS 因 Shirei 的 cocoabackend 经 AppKit 走 cgo,须 `CGO_ENABLED=1` 且在 Mac 上构建(见 `tools/build.go`)。 --- ## 已知限制 / 后续计划 - **macOS / Linux 托盘未实现**:当前关闭即退出(Windows 已按运行状态动态处理:运行中→托盘,未运行→退出)。 - **日志优雅退出(已基本闭环)**:正常退出路径(`app.Run()` 返回后 `defer`)已统一兜底——先停 frpc 子进程再优雅落盘,macOS / Linux / Windows 关窗均零丢失;另注册 SIGINT/SIGTERM/SIGHUP 信号处理器,覆盖 `kill`、终端中断、桌面会话注销/系统关机等信号类终止;后台写入线程的 flush 周期由 1s 收紧到 250ms,任何绕过清理的异常终止最多丢失约 250ms 日志。唯一残余风险是 **macOS 经 Cocoa 的 `exit()` 直接退出的 Quit 路径**(不经过 POSIX 信号、也不触发 Go defer)。 - 打包分发(安装包 / 签名)尚未处理。 --- ## 许可证 [MIT License](LICENSE) © 2026 Mirai. FrpGUI 是 frp 生态的第三方图形化工具,遵循 frp 的开源精神。第三方组件的许可证与归因详见 [THIRD-PARTY-LICENSES.md](THIRD-PARTY-LICENSES.md)。