# proxy-program **Repository Path**: dorne/proxy-program ## Basic Information - **Project Name**: proxy-program - **Description**: 代理透传cli工具 - **Primary Language**: Rust - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-31 - **Last Updated**: 2026-04-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # proxy-program 将任意可执行文件或命令"透传"到另一个位置。安装后,目标 exe 与源程序/命令完全等价——所有命令行参数、stdin/stdout/stderr 及退出码均原样转发,且**只生成单个 exe 文件**,无任何旁路文件。 支持系统托盘图标、控制台显隐控制、自定义工作目录、自定义 exe 图标,适合将独立应用包装为后台服务。 --- ## 快速上手 ```bash # 源程序模式:生成 nginx.exe 代理,实际指向原程序 proxy-program --source "D:\server\nginx\nginx.exe" --target "C:\Users\Dorne\.local\bin\nginx.exe" C:\Users\Dorne\.local\bin\nginx.exe -c nginx.conf -p D:\server\nginx ``` ```bash # 命令模式:生成 pip.exe,实际执行 python -m pip proxy-program --command "python -m pip" --target "D:\Dev\bin\pip.exe" --workdir "" D:\Dev\bin\pip.exe install requests --upgrade ``` ```bash # 嵌入脚本模式:将脚本内容嵌入 exe,原文件可删除 proxy-program --injectscript "C:\test.bat" --target "C:\test.exe" C:\test.exe arg1 arg2 ``` ```bash # 后台服务模式:隐藏控制台(--window 0)+ 托盘图标 + 自定义图标 proxy-program --source "D:\app\myapp.exe" --target "C:\myapp.exe" ^ --tray 1 --window 0 --appico ".\ico\Icon.ico" --trayico ".\ico\Icon.ico" ``` ```bash # 提取 exe 图标:从任意 exe 文件中提取全部内置图标到目录(.ico 格式) proxy-program --source "D:\app\myapp.exe" --saveico ".\myapp_icons" ``` --- ## CLI 参数 ### 提取图标功能 | 参数 | 说明 | |------|------| | `--source <路径>` | 要提取图标的目标 exe 文件路径 | | `--saveico <目录>` | 提取后的 .ico 文件保存目录(自动创建),会导出全部图标组 | 将 `--source` 与 `--saveico` 搭配使用,可以从任意 Windows exe 文件中提取其内置的全部图标组资源,并分别保存为标准的 `.ico` 文件(一个图标组一个文件)。每个导出的 `.ico` 包含该图标组下的所有尺寸和色深版本,可直接用于 `--appico` 和 `--trayico` 参数。 > ⚠️ 提取图标功能仅支持 Windows 平台,非 Windows 平台运行时会提示功能不支持。 ### 安装选项(三者互斥,必须搭配 `--target`) | 参数 | 说明 | |------|------| | `--source <路径>` | 要被代理的源程序路径,支持 `.exe` / `.bat` / `.cmd` / `.ps1`;运行时依赖原文件;与 `--saveico` 搭配使用时表示要提取图标的 exe 文件路径 | | `--injectscript <路径>` | 将脚本内容嵌入 exe,运行时无需原文件,支持 `.bat` / `.cmd` / `.ps1` | | `--command <命令>` | 要被代理的命令字符串(如 `"python -m pip"`),运行时通过 `cmd.exe /c` 执行 | ### `--source` 与 `--injectscript` 对比 | 特性 | `--source` | `--injectscript` | |------|-----------|-----------------| | 存储内容 | 源文件**路径** | 源文件**内容**(Base64 编码嵌入) | | 原文件删除后 | ❌ 无法运行 | ✅ 仍可运行 | | 支持 `.exe` | ✅ | ❌ | | 支持 `.bat` / `.cmd` / `.ps1` | ✅ | ✅ | | 代理 exe 大小 | 与 proxy-program.exe 相当 | 原 exe + 脚本内容 | | 工作目录默认值 | 源文件所在目录 | 脚本文件所在目录 | | 适用场景 | 源文件固定存在,或需代理 `.exe` | 脚本需要独立分发 / 原文件可删除 | > **运行时差异**:`--source` 直接调用原文件;`--injectscript` 将嵌入的脚本内容解码写入临时目录,执行后自动删除临时文件。 ### 公共选项 | 参数 | 默认 | 说明 | |------|------|------| | `--target <路径>` | — | 代理 exe 的生成位置,目录不存在时自动创建 | | `--tray <0\|1>` | `0` | 是否显示系统托盘图标;`1` = 开启,右键菜单见下方 | | `--window <0\|1>` | `1` | 是否显示控制台窗口;`1` = 显示(默认),`0` = 隐藏 | | `--appico <路径>` | — | 将 `.ico` 嵌入 exe 并写入 PE 图标资源(改变资源管理器 / 任务栏图标);若未指定 `--trayico` 也用作托盘图标 | | `--trayico <路径>` | — | 将 `.ico` 嵌入 overlay,运行时作为托盘图标(优先级高于 `--appico`) | | `--workdir <路径\|auto>` | `auto` | 子进程工作目录;`auto` = 源程序/脚本所在目录;`""` = 不变更 | | `-V`, `--version` | — | 显示版本号 | | `-h`, `--help` | — | 显示帮助信息 | ### 代理 exe 专用选项 | 参数 | 说明 | |------|------| | `--show-proxy-info` | 打印代理自身路径及嵌入的源信息后退出,不执行源程序 | --- ## 使用说明 ### 安装代理 **源程序模式**——代理一个可执行文件: ```bash proxy-program --source "D:\server\nginx\nginx.exe" --target "C:\bin\nginx.exe" ``` ``` Created successfully !!! Work Dir: D:\server\nginx Proxy Created: C:\bin\nginx.exe Source Path: D:\server\nginx\nginx.exe ``` **命令模式**——代理一个命令字符串: ```bash proxy-program --command "python -m pip" --target "D:\Dev\bin\pip.exe" --workdir "" ``` ``` Created successfully !!! Proxy Created: D:\Dev\bin\pip.exe Source Command: python -m pip ``` > `--workdir ""` 表示不切换目录(命令模式通常不需要固定工作目录)。 **嵌入脚本模式**——将脚本内容直接嵌入 exe,运行时无需原文件: ```bash proxy-program --injectscript "C:\scripts\service.bat" --target "C:\service.exe" --tray 1 --window 0 ``` ``` Created successfully !!! Work Dir: C:\scripts Proxy Created: C:\service.exe Injected Script: .bat (512 bytes) ``` **后台服务模式**——隐藏控制台、托盘图标、自定义图标: ```bash proxy-program --source "D:\app\myapp.exe" --target "C:\myapp.exe" ^ --tray 1 --window 0 --appico ".\ico\Icon.ico" --trayico ".\ico\Icon.ico" ``` ``` Created successfully !!! Work Dir: D:\app App Icon: embedded (15832 bytes) Tray Icon: embedded (15832 bytes) Proxy Created: C:\myapp.exe Source Path: D:\app\myapp.exe ``` - 运行 `C:\myapp.exe` 时控制台窗口自动隐藏,系统托盘出现自定义图标。 - 右键托盘菜单:**程序名**(标签)/ **显示窗口** / **隐藏窗口** / **退出程序**。 - 点击"退出程序"会强制终止子进程树(含 cmd.exe 启动的所有孙子进程)后退出。 - 若子进程自行退出,托盘图标仍保留,直到用户点击"退出程序"。 > 若只指定 `--appico` 而不指定 `--trayico`,托盘图标也会使用 `--appico` 的数据,无需重复传入相同文件。 ### 使用代理 安装完成后,直接调用目标 exe,参数原封不动传递给源程序/命令: ```bash C:\bin\nginx.exe -c nginx.conf # 等价于:D:\server\nginx\nginx.exe -c nginx.conf D:\Dev\bin\pip.exe install rich # 等价于:python -m pip install rich ``` ### 查看代理信息 对任意代理 exe 传入 `--show-proxy-info`,打印嵌入的源信息后退出: ```bash C:\bin\nginx.exe --show-proxy-info ``` ``` Proxy Path: C:\bin\nginx.exe Tray: disabled Window: hidden WorkDir: D:\server\nginx Source Path: D:\server\nginx\nginx.exe ``` ```bash C:\myapp.exe --show-proxy-info ``` ``` Proxy Path: C:\myapp.exe Tray: enabled Window: hidden WorkDir: D:\app App Icon: embedded (15832 bytes) Tray Icon: embedded (15832 bytes) Source Path: D:\app\myapp.exe ``` ```bash C:\service.exe --show-proxy-info ``` ``` Proxy Path: C:\service.exe Tray: enabled Window: hidden WorkDir: C:\scripts Script Type: bat Tmp Path: C:\Users\...\Temp\pxscript_.bat Script Content: ... ``` ### 重新安装 / 更换源 对同一 `--target` 重新执行任意安装命令即可,旧的嵌入数据自动清除,三种模式之间可自由切换: ```bash proxy-program --source "D:\server\nginx-new\nginx.exe" --target "C:\bin\nginx.exe" proxy-program --command "python3 -m pip" --target "D:\Dev\bin\pip.exe" --workdir "" proxy-program --injectscript "C:\scripts\service-v2.bat" --target "C:\service.exe" ^ --tray 1 --window 0 --appico ".\ico\Svc.ico" ``` --- ## 控制台与托盘行为 | `--window` | `--tray` | 行为 | |:-----------:|:--------:|------| | `1`(默认) | `0` | 控制台窗口可见,无托盘;等待子进程退出后代理退出 | | `1`(默认) | `1` | 控制台窗口可见,有托盘;可通过托盘"隐藏窗口"隐藏;手动点"退出程序"才退出 | | `0` | `0` | 控制台窗口隐藏,无托盘;等待子进程退出后代理退出 | | `0` | `1` | 控制台窗口隐藏,有托盘;可通过托盘"显示窗口"查看输出;子进程退出后托盘保留,手动点"退出程序"才退出 | > **注意**:从终端(PowerShell / cmd.exe)直接运行代理 exe 时,控制台为父终端共享,`--window 0` 不会隐藏父终端窗口,仅双击启动(独占控制台)时才生效。 --- ## 图标说明 | 参数 | 作用范围 | 存储位置 | 生效时机 | |------|----------|----------|----------| | `--appico` | exe 文件图标(资源管理器 / 任务栏) | 写入 PE 资源 + 嵌入 overlay | 安装时写入,立即生效 | | `--trayico` | 系统托盘图标 | 嵌入 overlay | 代理 exe 运行时加载 | **托盘图标优先级**:`--trayico` > `--appico` > 系统默认图标 ### 提取图标 使用 `--source --saveico <保存目录>` 可以提取任意 exe 文件的全部内置图标: ```bash proxy-program --source "C:\Windows\notepad.exe" --saveico ".\notepad_icons" ``` 提取后会在目录中生成多个 `.ico` 文件(按资源组命名),每个文件包含该组下所有尺寸和色深版本,可直接作为 `--appico` 和 `--trayico` 的输入使用。 --- ## 脚本文件中文乱码解决 各类型脚本所需编码不同,**务必按下表保存文件**: | 文件类型 | 文件编码 | 脚本开头 | |----------|----------|----------| | `.bat` / `.cmd` | **UTF-8(无 BOM)** | `chcp 65001 >nul` | | `.ps1` | **UTF-8 with BOM** | `& chcp.com 65001 \| Out-Null` + `$OutputEncoding = ...` | ### `.bat` / `.cmd` 文件保存为 **UTF-8(无 BOM)**,并在脚本开头切换控制台代码页: ```bat @echo off chcp 65001 >nul echo 中文内容正常显示 ``` > cmd.exe 通过 `chcp 65001` 识别 UTF-8,**不需要 BOM**;若保存为 UTF-8 with BOM,文件开头的三个 BOM 字节反而会导致第一行命令解析出错。 ### `.ps1` 文件保存为 **UTF-8 with BOM**,并在脚本开头切换编码: ```powershell & chcp.com 65001 | Out-Null $OutputEncoding = [Console]::OutputEncoding = [Text.Encoding]::UTF8 Write-Host "中文内容正常显示" ``` > PowerShell 5.x 读取无 BOM 的文件时按系统默认编码(GBK)解析,导致中文损坏。**UTF-8 with BOM** 是让 PowerShell 5.x 正确识别 UTF-8 的唯一可靠方式。 **VS Code 保存指定编码**:底部状态栏编码标识 → **Save with Encoding** → 选择对应编码。 --- ## 打包构建 **环境要求:** [Rust](https://rustup.rs/) stable 工具链 ```bash cargo build --release # 产物:target/release/proxy-program.exe ``` --- ## 实现原理 ### 安装模式 1. 根据参数类型准备嵌入内容: - `--source`:路径解析为绝对路径 - `--command`:加 `cmd://` 前缀 - `--injectscript`:读取文件字节,Base64 URL-safe 编码后加 `inject:://` 前缀 2. 读取自身 exe,自动剥离已有 overlay(支持幂等重装)。 3. 写入 `--target`,末尾追加 **overlay footer**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 配置前缀 + 内嵌内容(UTF-8) │ ← 长度可变 │ 格式:[T:x,C:y,W:base64url,A:base64url,I:base64url] │ │ T = tray(0/1) C = window(0/1) W = workdir │ │ A = appico I = trayico │ │ src 三种格式: │ │ <绝对路径> │ │ cmd://<命令> │ │ inject::// │ ├─────────────────────────────────────────────────────────────┤ │ data_len(u64 小端序,8 B) │ ├─────────────────────────────────────────────────────────────┤ │ MAGIC "PRXYMGC1"(8 B) │ └─────────────────────────────────────────────────────────────┘ ``` 4. 若指定了 `--appico`,通过 `BeginUpdateResource` / `UpdateResource` / `EndUpdateResource` 将图标写入代理 exe 的 PE 资源节(`RT_ICON` + `RT_GROUP_ICON`)。 > Windows PE 加载器只解析文件头,忽略末尾附加数据,不影响 exe 正常运行。 ### 代理模式 程序启动时优先检测 overlay,若存在则进入代理模式: 1. 解析 overlay,读取配置前缀(tray / window / workdir / appico / trayico)和源字符串。 2. 若参数含 `--show-proxy-info`:打印代理信息后退出。 3. 其余所有参数原样转发给源程序。 4. 应用 window 设置(隐藏/显示控制台窗口)。 5. 按 workdir 切换子进程工作目录后启动子进程(继承当前控制台)。 6. 若 tray 开启:从 overlay 读取 trayico(优先)或 appico 数据,通过 `CreateIconFromResourceEx` 创建 `HICON`,注册到系统托盘;子进程退出后托盘保留;用户点"退出程序"时以 `taskkill /F /T` 杀进程树后退出。 7. 若 tray 关闭:等待子进程退出,以相同退出码退出。 --- ## License Copyright 2026 Dorne Licensed under the [Apache License, Version 2.0](LICENSE).