调用 Windows 自带的 robocopy.exe(/MT 多线程)做高速批量搬运的桌面工具:
图形化任务管理、实时进度、日志完整落盘与节流展示、三级复制后校验、
/MIR 镜像二次确认、/L 试运行等。
源既可以是整个目录,也可以是单个文件:
- 目录:整体复制到目标目录下,并在目标端新建与源同名的子目录
(
D:\照片\2024→E:\备份\2024); - 单个文件:直接复制进目标目录、文件名不变,并自动关闭
/MIR(单文件没有镜像语义)。
技术栈:Tauri v2(Rust 后端 + WebView 前端),前端为 Vite + React + TypeScript + Tailwind CSS。
- 产品文档(面向使用者):
docs/README.md - 协作与分层约定(面向 AI/协作者):
AGENTS.md - 构建/打包/测试命令:见本文下方各节
.
├── Cargo.toml # workspace:crates/rc-core + src-tauri
├── crates/
│ └── rc-core/ # 纯逻辑库(不依赖 tauri,可独立单测)
│ └── src/
│ ├── models.rs # CopyTask/CopyOptions/TaskStatus/TaskEvent 数据契约
│ ├── winfs.rs # 盘符枚举/容量/长路径/路径关系/格式化
│ ├── scanner.rs # 源扫描 + TargetProgressTracker(hot/dirty/budget/prune)
│ ├── robocopy.rs # 命令拼装/OEM 解码/退出码/统计表解析/子进程执行
│ ├── verify.rs # 三级校验 + 1MB 分块哈希(线程池并发)
│ └── engine.rs # 调度线程 + worker + 进度轮询 + 日志节流落盘
├── src-tauri/ # Tauri bin:command 桥接 + 事件泵(唯一 UI 推送出口)
├── ui/ # 前端:Vite + React + TS + Tailwind
├── scripts/ # 打包脚本:build.ps1 / build.cmd(.cmd 为双击包装层)
├── run.ps1 / run.cmd # 启动脚本(.cmd 为双击包装层)
└── logs/ # 运行产物:每次执行的完整日志(已 gitignore)
- Rust 1.75+(stable)
- Node.js 18+ / npm
- Windows(复制依赖系统 robocopy.exe)
.\run.cmd # 启动脚本:开发模式(Vite 热更新 + Tauri 窗口)
.\run.cmd -Release # 直接运行已打包的 release 版本
.\run.cmd -Install # 强制重装依赖后启动
.\scripts\build.cmd # 打包:产出 dist\ 下的绿色运行文件(含单元测试)
.\scripts\build.cmd -SkipTest # 快速出包:跳过测试(内网推荐)
.\scripts\build.cmd -SkipTest -SkipInstall # 依赖已装好时的最快路径
.\scripts\build.cmd -Bundle # 额外生成 NSIS 安装包(需联网下载 NSIS)
.\scripts\build.cmd -Registry http://nexus.local.com:8081/repository/npm-proxy环境要求:原生 MSVC 工具链(rust-toolchain.toml 已把仓库固定到
stable-x86_64-pc-windows-msvc)。
产物在 dist\:robocopy-gui.exe 单文件。前端资源在编译期内嵌,
MSVC 下 WebView2Loader 静态链入,运行时不需要 Node、不需要安装、
也不需要旁附任何 DLL,直接拷这一个 exe 即可。-Bundle 才会额外做 NSIS 安装包。
首次构建若提示找不到工具链:
rustup toolchain install stable-x86_64-pc-windows-msvc(打包脚本会尝试自动安装)。
.cmd 只是包装层(自动选用 pwsh、自动补 UTF-8 BOM、绕过执行策略),
也可以直接调用 PowerShell 脚本:.\scripts\build.ps1 -SkipTest。
打包脚本本身位于 scripts/,运行时会把工作目录切回项目根,
产物路径与手动命令一致(见下方「产物位置」)。
注意:npm 默认走内网 registry 时可能 502,脚本默认使用官方源, 可用
-Registry覆盖。
npm install # 安装 @tauri-apps/cli(workspace 根)
npm --prefix ui install # 安装前端依赖
npm run tauri dev # 开发模式(自动起 Vite + cargo run)
# release 构建(等价于 build.ps1 的默认行为,顺序不可颠倒)
npm --prefix ui run build # 前端产物 → ui/dist(编译期内嵌)
cargo build --release -p robocopy-gui # → target/release/robocopy-gui.exe(单文件)
# 需要 NSIS 安装包时
npm run tauri build # exe + NSIS 安装包(需联网下载 NSIS)也可手动分离运行(调试更直观):
# 终端 1
npm --prefix ui run dev # Vite dev server → http://localhost:5173
# 终端 2
cargo run -p robocopy-gui # 直连 devUrl 调试 Rust 侧| 产物 | 路径 |
|---|---|
| 运行文件(主产物) | dist/robocopy-gui.exe(build.ps1 结束时从 target/release/ 复制,单文件) |
| 编译产物 | target/release/robocopy-gui.exe |
| NSIS 安装包(可选) | target/release/bundle/nsis/*.exe(仅 -Bundle,需联网下载 NSIS,内网常失败) |
exe 已内嵌前端资源,运行时不依赖 Node、不需要安装;目标机需具备 WebView2 运行时 (Win10/11 一般预装)。分发只需拷贝这一个 exe。
仓库用 rust-toolchain.toml 固定到 stable-x86_64-pc-windows-msvc(原生 MSVC)。
webview2-com-sys 的链接声明是:
#[cfg_attr(target_env = "msvc", link(name = "WebView2LoaderStatic", kind = "static"))]
#[cfg_attr(not(target_env = "msvc"), link(name = "WebView2Loader.dll"))]所以:
- MSVC(当前默认):
WebView2Loader静态链入 → 单文件 exe,分发无忧; - GNU/MinGW(已不再使用):动态链接
WebView2Loader.dll,缺它时进程以0xC0000135(找不到 DLL)立即退出,必须成对分发。
前置条件:安装
Visual Studio 生成工具
并勾选「使用 C++ 的桌面开发」(需要 link.exe 与 Windows SDK);
Rust 侧执行 rustup toolchain install stable-x86_64-pc-windows-msvc。
两者齐备后 cargo build / npm run tauri dev 都会自动走 MSVC,无需手动 vcvars。
任务执行时完整日志落盘到工作目录下的 logs/(命名:时间戳 + 任务名 + 任务 ID),
UI 仅做节流展示。以 -Release 方式启动时工作目录固定为项目根,故日志写入 ./logs/。
cargo test -p rc-core # 纯逻辑单测:命令拼装/退出码/统计表解析/
# 路径关系/扫描/校验/引擎端到端(真实 robocopy)
cd ui; npx tsc --noEmit # 前端类型检查