58 KiB
两台 Windows 工作主机数据同步备份实施方案
执行边界: 本文档只给出人工实施步骤。当前生成文档的过程不会安装软件、不会修改系统配置、不会启动同步、不会传输任何数据。
目标: 在笔记本 wddsh 与台式机 wdd 之间建立可长期运行的双向数据同步体系,覆盖微信数据、Git 项目仓库、开发工具配置,并保留可回滚版本。
总体架构: 使用 Syncthing 作为唯一持续同步引擎,承担双向、实时、冲突保留和版本留存。使用 rsync 只做微信数据的首次大体量灌入,减少 Syncthing 初次传输 30GB 海量小文件的时间。rsync 通过笔记本 WSL2 发起,SSH 连接台式机 Windows OpenSSH,再用 wsl rsync 调用台式机 WSL2 内的远端 rsync。实施过程先备份、再预演、再单项上线,避免一次性开放所有同步面。
技术栈: Windows 11、Syncthing、两端 WSL2、Windows OpenSSH、rsync、PowerShell、Windows 任务计划程序、JetBrains Settings Sync、VS Code Settings Sync。
0. 实施前总览
0.1 主机与路径
| 项目 | 笔记本 | 台式机 |
|---|---|---|
| Windows 用户 | wddsh |
wdd |
| 台式机局域网 IP | 不适用 | 192.168.1.194 |
| 微信数据目录 | C:\Users\wddsh\xwechat_files |
C:\Users\wdd\xwechat_files |
| Git 项目目录 | C:\Users\wddsh\Documents\IdeaProjects |
C:\Users\wdd\Documents\IdeaProjects |
| Syncthing Web UI | http://127.0.0.1:8384 |
http://127.0.0.1:8384 |
0.2 路径修正
原有微信 rsync 脚本中的目标路径示例是:
REMOTE_DST="/c/Users/wdd/wechat_files/xwechat_files"
本次实施必须改为用户已确认的台式机路径:
REMOTE_DST="/mnt/c/Users/wdd/xwechat_files"
如果你的 WSL 发行版能访问 /c/Users/...,也可以写成:
REMOTE_DST="/c/Users/wdd/xwechat_files"
实施前以 ls /mnt/c/Users/wdd 或 ls /c/Users/wdd 人工确认实际挂载路径,二选一固定,不要混用。
0.3 上线顺序
- 做台式机目标目录备份和空间检查。
- 配置笔记本 WSL2 SSH 客户端、台式机 WSL2 rsync 运行时、Windows OpenSSH 免密登录。
- 关闭两端微信,先做 rsync dry-run。
- 执行一次微信 rsync 首次灌入。
- 安装并配对两端 Syncthing。
- 先上线微信目录同步并观察。
- 再上线 Git 项目目录同步并观察。
- 最后上线少量开发工具配置同步。
- 配置 Syncthing 自启动、版本保留、巡检流程。
1. Phase 0:保护现场与回滚准备
Task 1:确认两端不在写入关键数据
操作位置: 笔记本和台式机都执行。
- Step 1:退出微信
在两台机器上右键系统托盘微信图标,选择退出。
- Step 2:确认微信进程已退出
打开 PowerShell,人工执行:
Get-Process Weixin -ErrorAction SilentlyContinue
预期结果:没有输出。
如果仍有输出,先在任务管理器中结束 Weixin.exe,再重复检查。
- Step 3:关闭 IDE 和编辑器
关闭 JetBrains IDE、VS Code、Cursor、Trae、终端中运行的开发服务。
- Step 4:确认 Git 没有正在执行的操作
在笔记本的 C:\Users\wddsh\Documents\IdeaProjects 下,对正在使用的仓库逐个执行:
git status
预期结果:没有 rebase、merge、cherry-pick、bisect 进行中。
如果存在进行中的 Git 操作,先在原机器上完成或中止该操作后再继续。
Task 2:确认台式机磁盘空间
操作位置: 台式机。
- Step 1:查看 C 盘可用空间
打开 PowerShell,人工执行:
Get-PSDrive C | Select-Object Name,Used,Free
判断标准:
-
微信数据约 30GB,至少预留 80GB。
-
Git 项目目录按实际大小再额外预留 30%。
-
Syncthing 版本保留会额外占用空间,首次上线建议 C 盘剩余空间不少于 120GB。
-
Step 2:确认台式机目标目录存在
人工执行:
New-Item -ItemType Directory -Force -Path "C:\Users\wdd\xwechat_files"
New-Item -ItemType Directory -Force -Path "C:\Users\wdd\Documents\IdeaProjects"
预期结果:目录存在;如果命令提示目录已存在,也属于正常。
Task 3:创建台式机本地保护备份
操作位置: 台式机。
- Step 1:创建备份根目录
人工执行:
New-Item -ItemType Directory -Force -Path "C:\Users\wdd\sync-preflight-backup"
- Step 2:备份现有微信目录
如果 C:\Users\wdd\xwechat_files 已有数据,人工执行:
robocopy "C:\Users\wdd\xwechat_files" "C:\Users\wdd\sync-preflight-backup\xwechat_files" /E /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ
预期结果:robocopy 退出码 0 到 7 都表示复制层面可接受;8 及以上表示有失败项,需要先查看输出。
- Step 3:备份现有 Git 项目目录
如果 C:\Users\wdd\Documents\IdeaProjects 已有数据,人工执行:
robocopy "C:\Users\wdd\Documents\IdeaProjects" "C:\Users\wdd\sync-preflight-backup\IdeaProjects" /E /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ /XD node_modules .gradle build dist target .idea\system
预期结果:同样以 robocopy 退出码 0 到 7 为可接受。
2. Phase 1:Windows OpenSSH 与两端 WSL2 rsync 准备
Task 4:确认两端 OpenSSH 可用
操作位置: 笔记本。
- Step 1:检查 ssh 客户端
人工执行:
ssh -V
预期结果:输出 OpenSSH 版本。
- Step 2:测试台式机 22 端口连通
人工执行:
Test-NetConnection 192.168.1.194 -Port 22
预期结果:TcpTestSucceeded : True。
- Step 3:如果端口不通,在台式机启用 OpenSSH Server
在台式机以管理员 PowerShell 人工执行:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'
如果状态不是 Installed,再人工执行:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
执行后回到笔记本重复 Test-NetConnection 192.168.1.194 -Port 22。
Task 5:配置 SSH 免密登录
操作位置: 笔记本。
- Step 1:检查本机 SSH 密钥
人工执行:
Test-Path "C:\Users\wddsh\.ssh\id_ed25519.pub"
预期结果:True。
- Step 2:如果没有密钥,创建 ed25519 密钥
人工执行:
ssh-keygen -t ed25519 -f "C:\Users\wddsh\.ssh\id_ed25519" -C "wddsh-r9000p-to-wdd-desktop"
提示 passphrase 时,可以直接回车留空,便于自动化 rsync。
- Step 3:把公钥追加到台式机
优先人工执行:
type "C:\Users\wddsh\.ssh\id_ed25519.pub" | ssh wdd@192.168.1.194 "mkdir .ssh 2>NUL & type con >> .ssh\authorized_keys"
如果台式机 SSH 进入的是 PowerShell 而不是 CMD,上面命令失败时改用:
$pub = Get-Content "C:\Users\wddsh\.ssh\id_ed25519.pub" -Raw
ssh wdd@192.168.1.194 "powershell -NoProfile -Command `"New-Item -ItemType Directory -Force -Path `$env:USERPROFILE\.ssh | Out-Null; Add-Content -Path `$env:USERPROFILE\.ssh\authorized_keys -Value '$pub'`""
- Step 4:验证免密 SSH
人工执行:
ssh -i "C:\Users\wddsh\.ssh\id_ed25519" wdd@192.168.1.194 "echo SSH_OK"
预期结果:
SSH_OK
Task 6:在 WSL2 中确认 rsync 可用
操作位置: 笔记本 WSL2。
- Step 1:进入 WSL2
在笔记本 PowerShell 人工执行:
wsl
- Step 2:确认 rsync 与 ssh 可用
在 WSL2 中人工执行:
rsync --version
ssh -V
预期结果:两个命令都输出版本。
- Step 3:如果 rsync 不存在,在 WSL2 中安装
Ubuntu/Debian 系 WSL2 人工执行:
sudo apt update
sudo apt install -y rsync openssh-client
执行后重复:
rsync --version
Task 6a:在台式机安装 WSL2 并准备远端 rsync
操作位置: 台式机。
目的: rsync 通过 SSH 工作时,远端也必须存在可执行的 rsync。本方案不在台式机 WSL2 内单独配置 SSH 服务,而是让 Windows OpenSSH 接收连接后执行 wsl rsync。
- Step 1:检查台式机是否已有 WSL2 发行版
在台式机 PowerShell 人工执行:
wsl -l -v
预期结果:至少有一个发行版,且 VERSION 是 2。
如果看到 Windows Subsystem for Linux has no installed distributions,说明还没有安装发行版,继续 Step 2。
- Step 2:安装 Ubuntu WSL2 发行版
在台式机管理员 PowerShell 人工执行:
wsl --install -d Ubuntu
如果系统提示重启,重启台式机。重启后打开 Ubuntu,按提示创建 Linux 用户名和密码。Linux 用户名可以使用:
wdd
- Step 3:确认默认 WSL 版本是 2
在台式机 PowerShell 人工执行:
wsl --set-default-version 2
wsl -l -v
如果 Ubuntu 显示 VERSION 1,人工执行:
wsl --set-version Ubuntu 2
然后重复:
wsl -l -v
- Step 4:在台式机 WSL2 中安装 rsync 和基础工具
在台式机 Ubuntu/WSL2 终端人工执行:
sudo apt update
sudo apt install -y rsync openssh-client coreutils
执行后验证:
rsync --version
test -d /mnt/c/Users/wdd && echo DESKTOP_WSL_CAN_ACCESS_WINDOWS_C
预期结果:
DESKTOP_WSL_CAN_ACCESS_WINDOWS_C
- Step 5:在台式机 WSL2 中创建微信目标目录
在台式机 Ubuntu/WSL2 终端人工执行:
mkdir -p /mnt/c/Users/wdd/xwechat_files
test -d /mnt/c/Users/wdd/xwechat_files && echo REMOTE_WECHAT_DIR_OK
预期结果:
REMOTE_WECHAT_DIR_OK
- Step 6:从台式机 Windows 侧验证
wsl rsync可被 OpenSSH 调用
回到台式机 PowerShell,人工执行:
wsl rsync --version
wsl test -d /mnt/c/Users/wdd/xwechat_files
预期结果:
-
wsl rsync --version输出 rsync 版本。 -
wsl test -d ...没有报错。 -
Step 7:从笔记本 Windows 侧验证远端
wsl rsync
在笔记本 PowerShell 人工执行:
ssh -i "C:\Users\wddsh\.ssh\id_ed25519" wdd@192.168.1.194 "wsl rsync --version"
ssh -i "C:\Users\wddsh\.ssh\id_ed25519" wdd@192.168.1.194 "wsl test -d /mnt/c/Users/wdd/xwechat_files && echo REMOTE_RSYNC_READY"
预期结果:
REMOTE_RSYNC_READY
如果第一条命令提示 wsl: command not found 或 rsync: not found,说明台式机 WSL2 或 rsync 没有配置完成,回到本 Task 的 Step 1 到 Step 6。
Task 7:在 WSL2 中配置 SSH Host 别名
操作位置: 笔记本 WSL2。
- Step 1:创建 SSH 配置目录
人工执行:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
- Step 2:编辑
~/.ssh/config
人工执行:
nano ~/.ssh/config
写入以下内容:
Host wdd-pink-station
HostName 192.168.1.194
Port 22
User wdd
IdentityFile /mnt/c/Users/wddsh/.ssh/id_ed25519
IdentitiesOnly yes
ServerAliveInterval 60
ServerAliveCountMax 3
StrictHostKeyChecking accept-new
保存后人工执行:
chmod 600 ~/.ssh/config
- Step 3:验证 Host 别名
人工执行:
test -f ~/.ssh/config && echo WSL_SSH_CONFIG_OK
ssh wdd-pink-station "echo Connected"
ssh wdd-pink-station "wsl rsync --version"
ssh wdd-pink-station "wsl test -d /mnt/c/Users/wdd/xwechat_files && echo REMOTE_WSL_RSYNC_OK"
预期结果:
WSL_SSH_CONFIG_OK
Connected
REMOTE_WSL_RSYNC_OK
如果出现:
Can't open user config file ~/.ssh/config: No such file or directory
说明你当前是在笔记本 WSL2 中运行 rsync,但还没有在该 WSL 用户目录下创建 ~/.ssh/config。回到本 Task 的 Step 1 和 Step 2,创建配置文件后再继续。Windows 侧的 C:\Users\wddsh\.ssh\config 不等于 WSL 侧的 ~/.ssh/config。
3. Phase 2:微信数据 rsync 首次灌入
Task 8:创建 dry-run 脚本
操作位置: 笔记本 WSL2。
- Step 1:创建脚本目录
人工执行:
mkdir -p ~/sync-scripts ~/wechat_backup/logs
- Step 2:创建 dry-run 脚本
人工执行:
nano ~/sync-scripts/wechat_initial_dry_run.sh
写入:
#!/usr/bin/env bash
set -euo pipefail
SRC="/mnt/c/Users/wddsh/xwechat_files"
REMOTE_HOST="wdd-pink-station"
REMOTE_DST="/mnt/c/Users/wdd/xwechat_files"
REMOTE_RSYNC_PATH="wsl rsync"
SSH_CONFIG="$HOME/.ssh/config"
RSYNC_SSH="ssh -F ${SSH_CONFIG}"
LOG_DIR="/mnt/c/Users/wddsh/wechat_backup/logs"
LOG_FILE="${LOG_DIR}/wechat_initial_dry_run_$(date +%Y%m%d_%H%M%S).log"
mkdir -p "$LOG_DIR"
if tasklist.exe 2>/dev/null | grep -qi "Weixin.exe"; then
echo "ERROR: Weixin.exe is still running. Exit WeChat before dry-run." | tee -a "$LOG_FILE"
exit 2
fi
if [ ! -d "$SRC" ]; then
echo "ERROR: Source path does not exist: $SRC" | tee -a "$LOG_FILE"
exit 3
fi
if [ ! -f "$SSH_CONFIG" ]; then
echo "ERROR: Missing WSL SSH config: $SSH_CONFIG" | tee -a "$LOG_FILE"
echo "Run Task 7 first. Windows C:\\Users\\wddsh\\.ssh\\config is not the same file." | tee -a "$LOG_FILE"
exit 4
fi
$RSYNC_SSH "$REMOTE_HOST" "wsl test -d $REMOTE_DST"
$RSYNC_SSH "$REMOTE_HOST" "wsl rsync --version" >/dev/null
rsync -rvzn \
--itemize-changes \
--partial \
--inplace \
--whole-file \
--delete \
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
--rsync-path="$REMOTE_RSYNC_PATH" \
--exclude="temp/" \
--exclude="cache/" \
--exclude="apm_record/" \
--exclude="crash_report/" \
--exclude="log/" \
--exclude="*.lock" \
--exclude="*.tmp" \
-e "$RSYNC_SSH" \
"${SRC}/" \
"${REMOTE_HOST}:${REMOTE_DST}/" \
2>&1 | tee -a "$LOG_FILE"
echo "Dry-run log: $LOG_FILE"
- Step 3:赋予执行权限
人工执行:
chmod +x ~/sync-scripts/wechat_initial_dry_run.sh
- Step 4:检查脚本没有混入 Markdown 代码围栏
人工执行:
tail -n 5 ~/sync-scripts/wechat_initial_dry_run.sh
bash -n ~/sync-scripts/wechat_initial_dry_run.sh
预期结果:
tail的最后一行应该是echo "Dry-run log: $LOG_FILE"。tail输出中不应该出现单独一行由三个反引号组成的 Markdown 代码围栏。bash -n没有任何输出,并返回成功。
如果 tail 看到单独一行 ```,说明复制 Markdown 文档时把代码块结束标记也复制进了脚本。删除该行:
sed -i '/^```$/d' ~/sync-scripts/wechat_initial_dry_run.sh
bash -n ~/sync-scripts/wechat_initial_dry_run.sh
bash -n 通过后再继续 Task 9。
Task 9:执行 rsync dry-run 并审阅
操作位置: 笔记本 WSL2。
- Step 1:运行 dry-run
人工执行:
~/sync-scripts/wechat_initial_dry_run.sh
预期结果:
- 输出大量
>f+++++++++或目录创建记录,表示将复制到台式机。 - 没有实际传输文件,因为参数包含
-n。 - 没有
deleting大量删除台式机有效数据;如果有,先停止并检查目标目录是否选错。
如果 rsync 已输出类似下面的统计信息:
total size is 36,671,651,105 speedup is ... (DRY RUN)
随后又报:
unexpected EOF while looking for matching ``'
说明 dry-run 主体已经完成,但脚本文件里混入了未配对的反引号,通常是末尾复制了 Markdown 代码围栏 ```。处理:
tail -n 10 ~/sync-scripts/wechat_initial_dry_run.sh
sed -i '/^```$/d' ~/sync-scripts/wechat_initial_dry_run.sh
bash -n ~/sync-scripts/wechat_initial_dry_run.sh
bash -n 没有输出后,再重新执行 dry-run。重新执行的目的只是确认脚本退出码正常;前一次 dry-run 已经证明 rsync 连接链路可用。
- Step 2:检查 dry-run 日志
人工执行:
ls -lh /mnt/c/Users/wddsh/wechat_backup/logs/
再打开最新的 wechat_initial_dry_run_*.log,重点检查:
-
源路径是
/mnt/c/Users/wddsh/xwechat_files/。 -
目标路径是
wdd-pink-station:/mnt/c/Users/wdd/xwechat_files/。 -
脚本包含
--rsync-path="wsl rsync",表示远端 rsync 由台式机 WSL2 提供。 -
脚本使用
-rvzn,不要使用-a。-a会隐式启用权限、属主、属组、时间戳等 Linux 元数据保留行为,不适合远端目标为 Windows/mnt/c的微信目录。 -
脚本包含
--size-only、--no-owner、--no-group、--no-perms、--no-times、--omit-dir-times,表示用文件大小判断增量,不在 Windows 盘上保留 Linux owner/group/permission/time 元数据。 -
脚本包含
--inplace、--whole-file,表示直接写目标文件并按整文件复制,减少 rsync 临时文件在 Windows 盘上的元数据操作。 -
没有把目标写到
/mnt/c/Users/wdd/wechat_files/xwechat_files/。 -
Step 3:如果 dry-run 报 SSH config 缺失
如果输出:
Can't open user config file ~/.ssh/config: No such file or directory
原因是当前脚本运行在笔记本 WSL2,-e "ssh -F ~/.ssh/config" 查找的是 WSL 用户目录下的:
~/.ssh/config
不是 Windows 目录:
C:\Users\wddsh\.ssh\config
处理步骤:
mkdir -p ~/.ssh
nano ~/.ssh/config
chmod 600 ~/.ssh/config
test -f ~/.ssh/config && echo WSL_SSH_CONFIG_OK
~/.ssh/config 内容必须与 Task 7 完全一致。完成后先验证:
ssh wdd-pink-station "echo Connected"
ssh wdd-pink-station "wsl rsync --version"
再重新运行:
~/sync-scripts/wechat_initial_dry_run.sh
如果以下手动验证已经成功:
test -f ~/.ssh/config && echo WSL_SSH_CONFIG_OK
ssh wdd-pink-station "echo Connected"
ssh wdd-pink-station "wsl rsync --version"
ssh wdd-pink-station "wsl test -d /mnt/c/Users/wdd/xwechat_files && echo REMOTE_WSL_RSYNC_OK"
但 dry-run 仍然报:
Can't open user config file ~/.ssh/config: No such file or directory
说明正在运行的 ~/sync-scripts/wechat_initial_dry_run.sh 仍是旧版本,脚本中还残留字面量 ~/.ssh/config。检查:
grep -n "ssh -F" ~/sync-scripts/wechat_initial_dry_run.sh
grep -n "RSYNC_SSH" ~/sync-scripts/wechat_initial_dry_run.sh
正确脚本必须包含:
SSH_CONFIG="$HOME/.ssh/config"
RSYNC_SSH="ssh -F ${SSH_CONFIG}"
并且 rsync 命令中必须是:
-e "$RSYNC_SSH" \
不能再出现:
-e "ssh -F ~/.ssh/config" \
- Step 4:如果 dry-run 报远端 rsync 或 wsl 不存在
如果输出包含:
wsl: command not found
rsync: command not found
rsync error: unexplained error (code 255)
说明台式机侧还没有完成 WSL2 或 rsync 准备。处理步骤:
- 回到 Task 6a,在台式机安装 WSL2 和 rsync。
- 在笔记本 WSL2 中执行:
ssh wdd-pink-station "wsl rsync --version"
ssh wdd-pink-station "wsl test -d /mnt/c/Users/wdd/xwechat_files && echo REMOTE_RSYNC_READY"
- 看到
REMOTE_RSYNC_READY后,再重新运行 dry-run。
Task 10:创建首次正式灌入脚本
操作位置: 笔记本 WSL2。
- Step 1:创建正式脚本
人工执行:
nano ~/sync-scripts/wechat_initial_sync.sh
写入:
#!/usr/bin/env bash
set -euo pipefail
SRC="/mnt/c/Users/wddsh/xwechat_files"
REMOTE_HOST="wdd-pink-station"
REMOTE_DST="/mnt/c/Users/wdd/xwechat_files"
REMOTE_RSYNC_PATH="wsl rsync"
SSH_CONFIG="$HOME/.ssh/config"
RSYNC_SSH="ssh -F ${SSH_CONFIG}"
LOG_DIR="/mnt/c/Users/wddsh/wechat_backup/logs"
LOG_FILE="${LOG_DIR}/wechat_initial_sync_$(date +%Y%m%d_%H%M%S).log"
mkdir -p "$LOG_DIR"
echo "======== WeChat initial rsync started at $(date '+%Y-%m-%d %H:%M:%S') ========" | tee -a "$LOG_FILE"
if tasklist.exe 2>/dev/null | grep -qi "Weixin.exe"; then
echo "ERROR: Weixin.exe is still running. Exit WeChat before initial sync." | tee -a "$LOG_FILE"
exit 2
fi
if [ ! -d "$SRC" ]; then
echo "ERROR: Source path does not exist: $SRC" | tee -a "$LOG_FILE"
exit 3
fi
if [ ! -f "$SSH_CONFIG" ]; then
echo "ERROR: Missing WSL SSH config: $SSH_CONFIG" | tee -a "$LOG_FILE"
echo "Run Task 7 first. Windows C:\\Users\\wddsh\\.ssh\\config is not the same file." | tee -a "$LOG_FILE"
exit 4
fi
$RSYNC_SSH "$REMOTE_HOST" "wsl mkdir -p $REMOTE_DST"
$RSYNC_SSH "$REMOTE_HOST" "wsl rsync --version" >/dev/null
rsync -rvz \
--info=progress2 \
--partial \
--inplace \
--whole-file \
--delete \
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
--rsync-path="$REMOTE_RSYNC_PATH" \
--exclude="temp/" \
--exclude="cache/" \
--exclude="apm_record/" \
--exclude="crash_report/" \
--exclude="log/" \
--exclude="*.lock" \
--exclude="*.tmp" \
-e "$RSYNC_SSH" \
"${SRC}/" \
"${REMOTE_HOST}:${REMOTE_DST}/" \
2>&1 | tee -a "$LOG_FILE"
status=${PIPESTATUS[0]}
echo "======== WeChat initial rsync finished with status ${status} at $(date '+%Y-%m-%d %H:%M:%S') ========" | tee -a "$LOG_FILE"
exit "$status"
- Step 2:赋予执行权限
人工执行:
chmod +x ~/sync-scripts/wechat_initial_sync.sh
- Step 3:检查正式脚本没有混入 Markdown 代码围栏
人工执行:
tail -n 5 ~/sync-scripts/wechat_initial_sync.sh
bash -n ~/sync-scripts/wechat_initial_sync.sh
预期结果:
tail的最后一行应该是exit "$status"。tail输出中不应该出现单独一行```。bash -n没有任何输出,并返回成功。
如果发现代码围栏,删除后复查:
sed -i '/^```$/d' ~/sync-scripts/wechat_initial_sync.sh
bash -n ~/sync-scripts/wechat_initial_sync.sh
Task 11:执行首次正式灌入
操作位置: 笔记本 WSL2。
- Step 1:再次确认微信未运行
人工执行:
tasklist.exe 2>/dev/null | grep -i "Weixin.exe" || echo "WeChat is not running"
预期结果:
WeChat is not running
- Step 2:运行正式灌入
人工执行:
~/sync-scripts/wechat_initial_sync.sh
预期结果:
- 首次可能运行 1 到 2 小时,取决于文件数量、磁盘和局域网速度。
- 退出状态为
0。 - 日志保存在
C:\Users\wddsh\wechat_backup\logs。
如果输出大量类似下面的警告:
rsync: [generator] chgrp "/mnt/c/Users/wdd/xwechat_files/..." failed: Operation not permitted (1)
根因是 rsync -a 默认尝试保留 Linux group 元数据,但目标目录位于台式机 Windows 盘 /mnt/c,Windows 文件系统不接受 WSL 的 chgrp。处理方式:
- 不需要手动修改这些目标文件。
- 暂停当前脚本或等待其结束都可以;如果已经传了很多文件,重新运行修正后的脚本会增量续传。
- 确认
~/sync-scripts/wechat_initial_sync.sh的 rsync 参数中已经包含:
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
- 语法检查:
bash -n ~/sync-scripts/wechat_initial_sync.sh
- 重新执行:
~/sync-scripts/wechat_initial_sync.sh
预期结果:不再出现 chgrp ... Operation not permitted。如果仍有少量 Permission denied,优先检查微信是否正在运行,或者目标文件是否被台式机微信、杀毒软件、索引服务占用。
如果输出类似下面的警告:
rsync: [generator] failed to set times on "/mnt/c/Users/wdd/xwechat_files/.": Operation not permitted (1)
根因是 rsync -a 默认保留时间戳,其中目录时间戳在 Windows /mnt/c 上可能无法设置。处理方式:
- 确认
~/sync-scripts/wechat_initial_sync.sh的 rsync 参数中已经包含:
--omit-dir-times \
- 同时保留前面的 Windows 元数据规避参数:
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
- 语法检查并重新执行:
bash -n ~/sync-scripts/wechat_initial_sync.sh
~/sync-scripts/wechat_initial_sync.sh
预期结果:不再出现 failed to set times on ".../."。--omit-dir-times 只跳过目录时间戳;如果仍然出现临时文件或普通文件的 failed to set times,说明还在使用 -a 或仍在保留文件时间戳,继续执行下面的 code 23 完整收敛方案。
如果脚本已经传输到 100%,最后输出:
rsync error: some files/attrs were not transferred (see previous errors) (code 23)
并且前面的错误主要是:
rsync: [receiver] failed to set times on "/mnt/c/Users/wdd/xwechat_files/...": Operation not permitted (1)
这是 Windows /mnt/c 文件时间戳元数据写入失败。内容已经基本传完,但 rsync 因属性设置失败返回 23。完整解决步骤:
- 不删除台式机
C:\Users\wdd\xwechat_files,保留已经传过去的 36GB 数据。 - 把
~/sync-scripts/wechat_initial_sync.sh中的 rsync 起始行从rsync -avz \改为:
rsync -rvz \
- 确认参数包含以下完整 Windows-safe 参数组:
--partial \
--inplace \
--whole-file \
--delete \
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
- 确认脚本中不再出现
rsync -avz:
grep -n "rsync -" ~/sync-scripts/wechat_initial_sync.sh
grep -n -- "--no-times\|--size-only\|--inplace" ~/sync-scripts/wechat_initial_sync.sh
bash -n ~/sync-scripts/wechat_initial_sync.sh
预期结果:
- 第一条显示
rsync -rvz \。 - 第二条能看到
--size-only、--inplace、--no-times。 bash -n没有输出。
- 重新执行一次收敛同步:
~/sync-scripts/wechat_initial_sync.sh
预期结果:
- 因为已经传过 36GB,第二次主要做增量检查和少量补齐。
- 不再出现
failed to set times。 - 最终退出状态为
0。
- 如果仍然出现
failed to set times,说明当前运行的还是旧脚本。直接检查:
nl -ba ~/sync-scripts/wechat_initial_sync.sh | sed -n '1,90p'
确认实际运行脚本与文档中的 Task 10 完全一致。
- Step 3:验证台式机文件规模
在台式机 PowerShell 人工执行:
(Get-ChildItem "C:\Users\wdd\xwechat_files" -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object).Count
在笔记本 PowerShell 人工执行:
(Get-ChildItem "C:\Users\wddsh\xwechat_files" -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object).Count
预期结果:两个数量接近。排除目录导致少量差异是正常的。
4. Phase 3:安装并配对 Syncthing
Task 12:下载并安装 Syncthing
操作位置: 笔记本和台式机都执行。
- Step 1:打开官方下载页
在浏览器访问:
https://syncthing.net/downloads/
选择 Windows 版本。Windows 当前没有官方安装器,官方文档给出的常规方式是下载压缩包并手动放置可执行文件。
- Step 2:创建安装目录
以普通用户或管理员 PowerShell 人工执行:
New-Item -ItemType Directory -Force -Path "C:\Tools\Syncthing"
- Step 3:解压
把下载的 Syncthing Windows 压缩包解压,把其中的 syncthing.exe 放到:
C:\Tools\Syncthing\syncthing.exe
- Step 4:首次交互启动
双击:
C:\Tools\Syncthing\syncthing.exe
Windows 防火墙弹窗出现时,勾选专用网络,允许访问。
- Step 5:打开 Web UI
访问:
http://127.0.0.1:8384
预期结果:打开 Syncthing 管理界面。
Task 13:加固 Syncthing Web UI
操作位置: 笔记本和台式机都执行。
- Step 1:进入 GUI 设置
在 Syncthing Web UI 中点击:
Actions -> Settings -> GUI
- Step 2:设置用户名和密码
填写:
GUI Authentication User: wddsh
GUI Authentication Password: 使用本机密码管理器生成的强密码
台式机用户名可以填:
wdd
- Step 3:限制监听地址
确认 GUI Listen Address 保持:
127.0.0.1:8384
不要改成 0.0.0.0:8384,除非后续明确需要远程访问 Web UI。
- Step 4:保存并重启 Syncthing
点击保存。提示重启时,点击重启。
Task 14:配对两台设备
操作位置: 两端 Syncthing Web UI。
- Step 1:在笔记本复制 Device ID
打开笔记本 Syncthing:
Actions -> Show ID
复制完整 Device ID。
- Step 2:在台式机添加笔记本
打开台式机 Syncthing:
Add Remote Device
填写:
Device ID: 粘贴笔记本 Device ID
Device Name: R9000P-wddsh
保存。
- Step 3:在台式机复制 Device ID
打开台式机 Syncthing:
Actions -> Show ID
复制完整 Device ID。
- Step 4:在笔记本添加台式机
打开笔记本 Syncthing:
Add Remote Device
填写:
Device ID: 粘贴台式机 Device ID
Device Name: Desktop-wdd
保存。
- Step 5:确认直连
在两端 Web UI 的 Remote Devices 中确认连接状态。
预期结果:
Connected
Connection Type: TCP LAN 或 QUIC LAN
如果显示 Relay,按以下顺序处理:
- 确认 Windows 网络配置为专用网络。
- 确认防火墙允许
C:\Tools\Syncthing\syncthing.exe。 - 确认两机在同一局域网。
- 重新启动 Syncthing。
5. Phase 4:微信目录 Syncthing 持续同步
Task 15:添加微信共享文件夹
操作位置: 先笔记本,后台式机。
- Step 1:在笔记本添加文件夹
笔记本 Syncthing Web UI 点击:
Add Folder
填写:
Folder Label: WeChat xwechat_files
Folder ID: wechat-xwechat-files
Folder Path: C:\Users\wddsh\xwechat_files
Folder Type: Send & Receive
- Step 2:共享给台式机
在 Sharing 页签勾选:
Desktop-wdd
- Step 3:设置扫描与监控
在 Advanced 页签设置:
Watch for Changes: Enabled
Full Rescan Interval: 300 seconds
Ignore Permissions: Enabled
- Step 4:启用版本控制
在 File Versioning 页签选择:
Staggered File Versioning
设置:
Maximum Age: 30 days
- Step 5:保存
点击 Save。
- Step 6:在台式机接受共享
台式机 Web UI 会弹出新文件夹邀请,点击 Add。
填写:
Folder Path: C:\Users\wdd\xwechat_files
Folder Type: Send & Receive
Watch for Changes: Enabled
Full Rescan Interval: 300 seconds
Ignore Permissions: Enabled
File Versioning: Staggered, 30 days
保存。
Task 16:配置微信 .stignore
操作位置: 笔记本和台式机的微信同步目录都配置。
- Step 1:在笔记本创建忽略文件
用记事本打开或创建:
C:\Users\wddsh\xwechat_files\.stignore
写入:
// Windows noise
(?i)desktop.ini
(?i)thumbs.db
// WeChat volatile files
temp/**
cache/**
apm_record/**
crash_report/**
log/**
*.lock
*.tmp
*.temp
*.bak.tmp
// Syncthing conflict review output should be handled manually
*.sync-conflict-*
- Step 2:在台式机创建同样的忽略文件
用记事本打开或创建:
C:\Users\wdd\xwechat_files\.stignore
写入同样内容。
Warning
db_storage 动态保护: 高级解决方案要求微信运行时临时将
db_storage排除同步(SQLite 数据库锁定状态下同步可能导致损坏)。.stignore中不要永久添加db_storage,否则聊天记录数据库将永远不会同步。下方 Task 18a 提供了自动保护脚本,可在微信运行时动态排除、关闭后自动恢复。
- Step 3:触发重新扫描
在两端 Syncthing Web UI 中,对 WeChat xwechat_files 点击:
Rescan
Task 17:微信同步验收
操作位置: 两台机器。
- Step 1:等待状态变为 Up to Date
在两端 Web UI 确认 WeChat xwechat_files 状态:
Up to Date
- Step 2:笔记本创建测试文件
在笔记本 PowerShell 人工执行:
Set-Content -Path "C:\Users\wddsh\xwechat_files\syncthing_probe_from_laptop.txt" -Value "from laptop $(Get-Date -Format s)"
- Step 3:台式机确认收到
在台式机 PowerShell 人工执行:
Get-Content "C:\Users\wdd\xwechat_files\syncthing_probe_from_laptop.txt"
预期结果:能看到 from laptop。
- Step 4:台式机创建反向测试文件
在台式机 PowerShell 人工执行:
Set-Content -Path "C:\Users\wdd\xwechat_files\syncthing_probe_from_desktop.txt" -Value "from desktop $(Get-Date -Format s)"
- Step 5:笔记本确认收到
在笔记本 PowerShell 人工执行:
Get-Content "C:\Users\wddsh\xwechat_files\syncthing_probe_from_desktop.txt"
预期结果:能看到 from desktop。
- Step 6:删除测试文件
在笔记本 PowerShell 人工执行:
Remove-Item "C:\Users\wddsh\xwechat_files\syncthing_probe_from_laptop.txt" -Force
Remove-Item "C:\Users\wddsh\xwechat_files\syncthing_probe_from_desktop.txt" -Force
等待删除同步到台式机。
Task 18:微信日常使用规则
- Step 1:切换电脑前退出微信
从笔记本切到台式机,或从台式机切到笔记本前,先退出微信。
- Step 2:等待 Syncthing 同步完成
打开 http://127.0.0.1:8384,确认微信文件夹是:
Up to Date
- Step 3:再在另一台电脑登录微信
不要在 Syncthing 显示 Syncing、Scanning、Out of Sync 时切换微信主力设备。
Task 18a:微信 db_storage 动态保护(建议配置)
Important
高级解决方案要求:微信运行时临时排除
db_storage目录(SQLite 数据库锁定状态下同步可能导致文件损坏),微信关闭后恢复同步。以下脚本自动完成这一切换,建议配合任务计划程序每 2 分钟执行一次。
操作位置: 笔记本和台式机都配置。
- Step 1:获取 Syncthing API Key
在 Syncthing Web UI 中复制:
Actions -> Settings -> General -> API Key
然后在本机 PowerShell 中保存到当前用户目录下的受限文件:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\syncthing-scripts"
$apiKey = Read-Host "Paste this machine's Syncthing API Key"
Set-Content -Path "$env:USERPROFILE\syncthing-scripts\syncthing-api-key.txt" -Value $apiKey -NoNewline
icacls "$env:USERPROFILE\syncthing-scripts\syncthing-api-key.txt" /inheritance:r
icacls "$env:USERPROFILE\syncthing-scripts\syncthing-api-key.txt" /grant:r "$env:USERNAME:F"
预期结果:syncthing-api-key.txt 只允许当前 Windows 用户读取。
- Step 2:创建保护脚本
人工执行创建脚本目录:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\syncthing-scripts"
用记事本创建脚本文件:
笔记本:C:\Users\wddsh\syncthing-scripts\wechat-db-guard.ps1
台式机:C:\Users\wdd\syncthing-scripts\wechat-db-guard.ps1
写入以下内容(两端相同):
param(
[Parameter(Mandatory)][string]$StIgnorePath,
[Parameter(Mandatory)][string]$ApiKeyPath
)
$ErrorActionPreference = "Stop"
$guardComment = "// [AUTO-GUARD] db_storage excluded while WeChat is running"
$guardLine = "**/db_storage/**"
$wechatRunning = [bool](Get-Process Weixin -ErrorAction SilentlyContinue)
if (-not (Test-Path $StIgnorePath)) {
Write-Host "ERROR: .stignore not found: $StIgnorePath"
exit 1
}
if (-not (Test-Path $ApiKeyPath)) {
Write-Host "ERROR: Syncthing API key file not found: $ApiKeyPath"
exit 2
}
$ApiKey = (Get-Content $ApiKeyPath -Raw).Trim()
$content = Get-Content $StIgnorePath -Raw
$hasGuard = $content.Contains($guardLine)
if ($wechatRunning -and -not $hasGuard) {
Add-Content -Path $StIgnorePath -Value "`n$guardComment`n$guardLine"
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:8384/rest/db/scan?folder=wechat-xwechat-files" -Headers @{"X-API-Key"=$ApiKey} | Out-Null
Write-Host "[$(Get-Date -Format s)] GUARD ON: db_storage excluded (WeChat running)"
}
elseif (-not $wechatRunning -and $hasGuard) {
(Get-Content $StIgnorePath) | Where-Object { $_ -ne $guardLine -and $_ -ne $guardComment } | Set-Content $StIgnorePath
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:8384/rest/db/scan?folder=wechat-xwechat-files" -Headers @{"X-API-Key"=$ApiKey} | Out-Null
Write-Host "[$(Get-Date -Format s)] GUARD OFF: db_storage syncing (WeChat closed)"
}
else {
Write-Host "[$(Get-Date -Format s)] No action needed"
}
- Step 3:手动验证脚本
微信运行时在 PowerShell 执行(笔记本示例):
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\syncthing-scripts\wechat-db-guard.ps1" -StIgnorePath "C:\Users\wddsh\xwechat_files\.stignore" -ApiKeyPath "$env:USERPROFILE\syncthing-scripts\syncthing-api-key.txt"
台式机将 -StIgnorePath 替换为 "C:\Users\wdd\xwechat_files\.stignore"。
预期结果:输出 GUARD ON,检查 .stignore 末尾出现 **/db_storage/**。
关闭微信后再次执行,预期输出 GUARD OFF,guard 行被移除。
- Step 4:配置定时执行
打开任务计划程序(taskschd.msc),创建新任务:
Name: WeChat DB Guard
Triggers: At log on, Repeat every 2 minutes indefinitely
Action: Start a program
Program/script: powershell.exe
笔记本 Add arguments:
-ExecutionPolicy Bypass -WindowStyle Hidden -File "C:\Users\wddsh\syncthing-scripts\wechat-db-guard.ps1" -StIgnorePath "C:\Users\wddsh\xwechat_files\.stignore" -ApiKeyPath "C:\Users\wddsh\syncthing-scripts\syncthing-api-key.txt"
台式机 Add arguments:
-ExecutionPolicy Bypass -WindowStyle Hidden -File "C:\Users\wdd\syncthing-scripts\wechat-db-guard.ps1" -StIgnorePath "C:\Users\wdd\xwechat_files\.stignore" -ApiKeyPath "C:\Users\wdd\syncthing-scripts\syncthing-api-key.txt"
Settings 页:
勾选 Allow task to be run on demand
取消勾选 Stop the task if it runs longer than
If the task is already running: Do not start a new instance
6. Phase 5:Git 项目仓库 Syncthing 同步
Task 19:实施前清理 Git 工作状态
操作位置: 笔记本和台式机。
- Step 1:关闭 IDE
关闭所有可能写入项目目录的 IDE、编辑器、构建工具、终端。
- Step 2:检查常用仓库状态
在每个活跃仓库执行:
git status
预期结果:
-
没有 rebase、merge、cherry-pick 进行中。
-
如果有重要未提交改动,先在原机器上 commit 或 stash。
-
Step 3:删除临时锁文件
只在确认没有 Git 命令运行时,人工检查并删除:
Get-ChildItem "C:\Users\wddsh\Documents\IdeaProjects" -Recurse -Force -Filter "index.lock"
如果确认是残留锁文件,删除:
Get-ChildItem "C:\Users\wddsh\Documents\IdeaProjects" -Recurse -Force -Filter "index.lock" | Remove-Item -Force
台式机同样检查:
Get-ChildItem "C:\Users\wdd\Documents\IdeaProjects" -Recurse -Force -Filter "index.lock"
Task 20:添加 Git 项目共享文件夹
操作位置: 先笔记本,后台式机。
- Step 1:在笔记本添加文件夹
Syncthing Web UI 点击:
Add Folder
填写:
Folder Label: IdeaProjects
Folder ID: ideaprojects
Folder Path: C:\Users\wddsh\Documents\IdeaProjects
Folder Type: Send & Receive
- Step 2:共享给台式机
Sharing 页签勾选:
Desktop-wdd
- Step 3:设置高级参数
Advanced 页签设置:
Watch for Changes: Enabled
Full Rescan Interval: 600 seconds
Ignore Permissions: Enabled
- Step 4:启用版本控制
File Versioning 页签选择:
Staggered File Versioning
Maximum Age: 30 days
- Step 5:台式机接受共享
台式机 Web UI 收到邀请后点击 Add,填写:
Folder Path: C:\Users\wdd\Documents\IdeaProjects
Folder Type: Send & Receive
Watch for Changes: Enabled
Full Rescan Interval: 600 seconds
Ignore Permissions: Enabled
File Versioning: Staggered, 30 days
保存。
Task 21:配置 Git 项目 .stignore
操作位置: 笔记本和台式机的 IdeaProjects 根目录都配置。
- Step 1:在笔记本创建忽略文件
创建或编辑:
C:\Users\wddsh\Documents\IdeaProjects\.stignore
写入:
// Windows noise
(?i)desktop.ini
(?i)thumbs.db
// Dependency directories
**/node_modules/**
**/.pnpm-store/**
**/.yarn/cache/**
**/.gradle/**
**/.m2/repository/**
**/vendor/**
// Build outputs
**/build/**
**/dist/**
**/out/**
**/target/**
**/.next/**
**/.nuxt/**
**/.vite/**
**/coverage/**
// Python caches
**/__pycache__/**
**/*.pyc
**/.pytest_cache/**
**/.mypy_cache/**
**/.ruff_cache/**
// IDE volatile files
**/.idea/workspace.xml
**/.idea/tasks.xml
**/.idea/usage.statistics.xml
**/.idea/shelf/**
**/*.iws
**/.vscode/.ropeproject/**
// Logs and temp
**/*.log
**/*.tmp
**/*.temp
**/.DS_Store
// Git transient lock files; do not ignore .git itself
**/.git/index.lock
**/.git/HEAD.lock
**/.git/config.lock
// Syncthing conflicts require manual resolution
**/*.sync-conflict-*
- Step 2:在台式机创建同样的忽略文件
创建或编辑:
C:\Users\wdd\Documents\IdeaProjects\.stignore
写入同样内容。
- Step 3:触发重新扫描
在两端 Web UI 对 IdeaProjects 点击:
Rescan
Task 22:Git 项目同步验收
操作位置: 两台机器。
- Step 1:等待状态为 Up to Date
在两端确认 IdeaProjects 文件夹状态:
Up to Date
- Step 2:笔记本创建测试文件
在笔记本 PowerShell 人工执行:
Set-Content -Path "C:\Users\wddsh\Documents\IdeaProjects\syncthing_project_probe.txt" -Value "from laptop $(Get-Date -Format s)"
- Step 3:台式机确认收到
在台式机 PowerShell 人工执行:
Get-Content "C:\Users\wdd\Documents\IdeaProjects\syncthing_project_probe.txt"
预期结果:能看到 from laptop。
- Step 4:台式机创建反向测试文件
在台式机 PowerShell 人工执行:
Set-Content -Path "C:\Users\wdd\Documents\IdeaProjects\syncthing_project_probe_desktop.txt" -Value "from desktop $(Get-Date -Format s)"
- Step 5:笔记本确认收到
在笔记本 PowerShell 人工执行:
Get-Content "C:\Users\wddsh\Documents\IdeaProjects\syncthing_project_probe_desktop.txt"
- Step 6:删除测试文件
在笔记本 PowerShell 人工执行:
Remove-Item "C:\Users\wddsh\Documents\IdeaProjects\syncthing_project_probe.txt" -Force
Remove-Item "C:\Users\wddsh\Documents\IdeaProjects\syncthing_project_probe_desktop.txt" -Force
Task 23:Git 日常使用规则
- Step 1:同一时间只在一台机器开发同一个仓库
如果笔记本正在编辑某个仓库,台式机只做查看或等待同步完成。
- Step 2:大改动先 commit
开始跨机器切换前,在当前机器执行:
git status
git add -A
git commit -m "wip: save work before machine switch"
如果不想产生 commit,使用:
git stash push -u -m "machine switch"
- Step 3:切换机器前等待 Up to Date
确认 IdeaProjects 在 Syncthing 中为:
Up to Date
- Step 4:另一台机器先检查状态再开发
在目标机器仓库中执行:
git status
确认没有异常冲突文件后再打开 IDE。
7. Phase 6:开发工具配置同步
Task 24:优先启用内置配置同步
操作位置: 两台机器。
- Step 1:JetBrains IDE 启用 Settings Sync
在 IntelliJ IDEA、WebStorm 或其他 JetBrains IDE 中打开:
File -> Settings -> Settings Sync
登录同一个 JetBrains 账号,启用同步。
- Step 2:VS Code 启用 Settings Sync
在 VS Code 中执行:
Manage -> Settings Sync is On
登录同一个 GitHub 或 Microsoft 账号。
- Step 3:不要用 Syncthing 同步 JetBrains 整个配置目录
不要同步整个:
%APPDATA%\JetBrains
原因:其中包含缓存、索引、机器路径和可能的平台特定状态,跨机器直接同步容易导致 IDE 异常。
Task 25:同步 Windows Terminal 配置
操作位置: 如果两端都使用 Microsoft Store 版 Windows Terminal。
- Step 1:确认配置路径
笔记本路径:
C:\Users\wddsh\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState
台式机路径:
C:\Users\wdd\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState
- Step 2:在 Syncthing 添加独立文件夹
笔记本添加:
Folder Label: Windows Terminal
Folder ID: windows-terminal-settings
Folder Path: C:\Users\wddsh\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState
Folder Type: Send & Receive
共享给 Desktop-wdd。
- Step 3:台式机接受共享
填写:
Folder Path: C:\Users\wdd\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState
Folder Type: Send & Receive
- Step 4:配置
.stignore
两端的 LocalState\.stignore 写入:
*.tmp
*.log
*.bak
Task 26:一次性迁移 Git 全局配置
操作位置: 笔记本导出,台式机导入。
- Step 1:在笔记本查看 Git 全局配置
人工执行:
git config --global --list --show-origin
- Step 2:在笔记本复制全局配置文件
全局配置文件通常为:
C:\Users\wddsh\.gitconfig
人工复制到台式机:
C:\Users\wdd\.gitconfig
- Step 3:台式机审阅绝对路径
在台式机 PowerShell 执行:
notepad "C:\Users\wdd\.gitconfig"
检查并修正包含 C:\Users\wddsh 的路径。
Task 27:一次性迁移 SSH 配置
操作位置: 手动操作,不建议 Syncthing 长期同步私钥。
- Step 1:复制 SSH config,不复制私钥前先评估
可复制:
C:\Users\wddsh\.ssh\config
到:
C:\Users\wdd\.ssh\config
- Step 2:私钥按需迁移
如果确实需要同一套私钥,在台式机创建:
New-Item -ItemType Directory -Force -Path "C:\Users\wdd\.ssh"
然后手动复制:
C:\Users\wddsh\.ssh\id_ed25519
C:\Users\wddsh\.ssh\id_ed25519.pub
到:
C:\Users\wdd\.ssh\
- Step 3:修正权限
在台式机 PowerShell 执行:
icacls "C:\Users\wdd\.ssh\id_ed25519" /inheritance:r
icacls "C:\Users\wdd\.ssh\id_ed25519" /grant:r "$env:USERNAME:F"
8. Phase 7:Syncthing 自启动与运行参数
Task 28:优先用任务计划程序随用户登录启动
操作位置: 笔记本和台式机都执行。
- Step 1:打开任务计划程序
按 Win + R,输入:
taskschd.msc
- Step 2:创建任务
点击:
Task Scheduler Library -> Create Task
General 页填写:
Name: Syncthing
Run only when user is logged on
- Step 3:设置触发器
Triggers 页点击 New:
Begin the task: At log on
Specific user: 当前用户
- Step 4:设置动作
Actions 页点击 New:
Action: Start a program
Program/script: C:\Tools\Syncthing\syncthing.exe
Add arguments: --no-console --no-browser --logfile="C:\Tools\Syncthing\syncthing.log" --logflags=3
Start in: C:\Tools\Syncthing
Tip
--logfile将 Syncthing 运行日志持久化到文件,便于事后排查同步异常。--logflags=3输出日期+时间前缀。日志文件会随运行时间增长,可在每月巡检时检查大小或清空。
- Step 5:设置条件
Conditions 页:
取消勾选 Start the task only if the computer is on AC power
取消勾选 Stop if the computer switches to battery power
- Step 6:设置运行策略
Settings 页:
勾选 Allow task to be run on demand
勾选 Run task as soon as possible after a scheduled start is missed
取消勾选 Stop the task if it runs longer than
- Step 7:保存并测试
保存任务后,右键任务选择:
Run
打开:
http://127.0.0.1:8384
预期结果:Syncthing Web UI 可访问。
Task 29:不优先使用 Windows 服务模式
本方案不把 NSSM 服务模式作为默认做法。原因:
- 当前是个人工作站场景,不是无人值守服务器。
- Syncthing 官方文档也更推荐终端用户随登录启动。
- 服务模式需要额外处理运行用户、GUI 密码、文件权限和安全边界。
只有在台式机长期无人登录但仍需同步时,才考虑 NSSM 服务模式。
Task 29a:配置 Syncthing 全局安全参数
操作位置: 笔记本和台式机都执行。
- Step 1:设置最小磁盘剩余空间
在 Syncthing Web UI 中打开:
Actions -> Settings -> General
找到 Minimum Free Disk Space,设置为:
5 %
保存。此参数确保磁盘空间不足时 Syncthing 自动暂停同步,防止写满系统盘导致系统异常。
- Step 2:确认日志文件已生成
Task 28 中已通过启动参数 --logfile 启用日志持久化。确认日志文件存在:
Test-Path "C:\Tools\Syncthing\syncthing.log"
预期结果:True。
如日志文件增长过大,可在巡检时清空:
Clear-Content "C:\Tools\Syncthing\syncthing.log"
9. Phase 8:监控、巡检与冲突处理
Task 30:每日快速巡检
操作位置: 任意一台机器。
- Step 1:打开 Syncthing Web UI
访问:
http://127.0.0.1:8384
- Step 2:检查三个状态
确认:
Remote Device: Connected
WeChat xwechat_files: Up to Date
IdeaProjects: Up to Date
如果 Windows Terminal 配置也纳入同步,确认:
Windows Terminal: Up to Date
- Step 3:检查 Recent Changes
点击:
Recent Changes
确认没有异常的大批量删除。
Task 31:每周冲突文件检查
操作位置: 笔记本和台式机。
- Step 1:查找冲突文件
笔记本 PowerShell:
Get-ChildItem "C:\Users\wddsh\xwechat_files","C:\Users\wddsh\Documents\IdeaProjects" -Recurse -Force -Filter "*sync-conflict*" -ErrorAction SilentlyContinue
台式机 PowerShell:
Get-ChildItem "C:\Users\wdd\xwechat_files","C:\Users\wdd\Documents\IdeaProjects" -Recurse -Force -Filter "*sync-conflict*" -ErrorAction SilentlyContinue
- Step 2:处理 Git 冲突文件
如果冲突文件出现在 Git 仓库中:
- 打开原文件和
*.sync-conflict-*文件。 - 使用 IDE diff 工具比较内容。
- 把需要保留的内容合并到原文件。
- 删除
*.sync-conflict-*文件。 - 执行:
git status
git diff
git add -A
git commit -m "fix: resolve syncthing conflict"
- Step 3:处理微信冲突文件
微信数据冲突不要手动改数据库文件。处理规则:
- 如果冲突文件是图片、视频、语音等媒体文件,保留较新的或两者都保留。
- 如果冲突文件是数据库文件,先停止两端微信和 Syncthing。
- 从
.stversions中找出最近正常版本。 - 复制出备份后,再决定恢复哪一份。
- 不确定时,不删除任何数据库冲突文件。
Task 32:每月容量检查
操作位置: 两台机器。
- Step 1:检查 C 盘空间
PowerShell:
Get-PSDrive C | Select-Object Name,Used,Free
- Step 2:检查 Syncthing 版本目录
笔记本:
Get-ChildItem "C:\Users\wddsh\xwechat_files\.stversions","C:\Users\wddsh\Documents\IdeaProjects\.stversions" -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum
台式机:
Get-ChildItem "C:\Users\wdd\xwechat_files\.stversions","C:\Users\wdd\Documents\IdeaProjects\.stversions" -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum
- Step 3:空间不足时先降低版本保留天数
在 Syncthing Web UI 中进入对应文件夹:
Edit -> File Versioning -> Maximum Age
从:
30 days
临时调整为:
14 days
不要直接删除正在使用中的同步目录。
10. Phase 9:手动触发 Syncthing 重新扫描
Task 33:从 Web UI 手动扫描
操作位置: 任意一端。
- Step 1:打开文件夹菜单
在 Syncthing Web UI 中点击目标文件夹。
- Step 2:点击 Rescan
等待状态从 Scanning 变为:
Up to Date
Task 34:准备 PowerShell API 扫描脚本
操作位置: 两台机器,可选。
- Step 1:获取 API Key
Syncthing Web UI:
Actions -> Settings -> General -> API Key
复制 API Key。
- Step 2:创建脚本目录
PowerShell 人工执行:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\syncthing-scripts"
- Step 3:创建
rescan-wechat.ps1
用记事本创建:
%USERPROFILE%\syncthing-scripts\rescan-wechat.ps1
写入:
$ErrorActionPreference = "Stop"
$apiKey = Read-Host "Paste this machine's Syncthing API Key"
$headers = @{ "X-API-Key" = $apiKey }
$uri = "http://127.0.0.1:8384/rest/db/scan?folder=wechat-xwechat-files"
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers
- Step 4:创建
rescan-ideaprojects.ps1
用记事本创建:
%USERPROFILE%\syncthing-scripts\rescan-ideaprojects.ps1
写入:
$ErrorActionPreference = "Stop"
$apiKey = Read-Host "Paste this machine's Syncthing API Key"
$headers = @{ "X-API-Key" = $apiKey }
$uri = "http://127.0.0.1:8384/rest/db/scan?folder=ideaprojects"
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers
- Step 5:手动触发扫描
PowerShell 人工执行:
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\syncthing-scripts\rescan-wechat.ps1"
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\syncthing-scripts\rescan-ideaprojects.ps1"
预期结果:返回 JSON 或空响应,Web UI 中对应文件夹进入扫描状态。
11. 回滚方案
Task 35:暂停 Syncthing 同步
操作位置: 两端 Syncthing Web UI。
- Step 1:暂停远程设备
对 Remote Device 点击:
Pause
- Step 2:暂停问题文件夹
对问题文件夹点击:
Pause
Task 36:从预实施备份恢复台式机目录
操作位置: 台式机。
- Step 1:恢复微信目录
确认 Syncthing 已暂停后,人工执行:
robocopy "C:\Users\wdd\sync-preflight-backup\xwechat_files" "C:\Users\wdd\xwechat_files" /MIR /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ
- Step 2:恢复 Git 项目目录
确认 Syncthing 已暂停后,人工执行:
robocopy "C:\Users\wdd\sync-preflight-backup\IdeaProjects" "C:\Users\wdd\Documents\IdeaProjects" /MIR /COPY:DAT /DCOPY:DAT /R:1 /W:1 /XJ
- Step 3:删除 Syncthing 文件夹配置
在 Syncthing Web UI 中对问题文件夹选择:
Edit -> Remove
只移除 Syncthing 配置,不手动删除实际数据目录。
Task 37:从 Syncthing 版本目录恢复单个文件
操作位置: 文件所在机器。
- Step 1:打开版本目录
微信版本目录通常在:
C:\Users\wddsh\xwechat_files\.stversions
C:\Users\wdd\xwechat_files\.stversions
Git 项目版本目录通常在:
C:\Users\wddsh\Documents\IdeaProjects\.stversions
C:\Users\wdd\Documents\IdeaProjects\.stversions
- Step 2:复制目标版本到临时目录
在资源管理器中打开 .stversions,按文件名和修改时间找到要恢复的版本,先复制到:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\restore-review"
不要剪切,不要直接覆盖原文件。
- Step 3:人工 diff 后恢复
确认内容正确后,再复制回原路径。不要直接在 .stversions 中编辑文件。
12. 最终验收清单
- 两台机器 Syncthing 都能访问
http://127.0.0.1:8384。 - 两台机器互相显示
Connected,并且不是 Relay 优先连接。 WeChat xwechat_files两端都是Up to Date。- 微信测试文件能笔记本到台式机、台式机到笔记本双向同步。
IdeaProjects两端都是Up to Date。- Git 项目测试文件能双向同步。
.stignore已存在于微信目录和IdeaProjects根目录。- 微信和 Git 文件夹都启用了 Staggered File Versioning,保留 30 天。
- Syncthing 已通过任务计划程序随用户登录启动。
- 切换微信登录设备前,已经形成“退出微信 -> 等待 Up to Date -> 另一端登录”的习惯。
- 切换 Git 开发机器前,已经形成“commit/stash -> 等待 Up to Date -> 另一端 git status”的习惯。
13. 参考依据
- 原始方案:
35-黑苹果DELL/7-数据同步备份-高级解决方案.md - 微信 rsync 基础脚本:
35-黑苹果DELL/6-微信数据备份.md - Syncthing 下载页:
https://syncthing.net/downloads/ - Syncthing Windows 自启动说明:
https://docs.syncthing.net/users/autostart.html - Syncthing 防火墙与直连排查:
https://docs.syncthing.net/users/firewall.html - Syncthing 忽略规则:
https://docs.syncthing.net/users/ignoring.html - Syncthing 文件版本控制:
https://docs.syncthing.net/users/versioning.html - Syncthing 手动扫描 API:
https://docs.syncthing.net/rest/db-scan-post.html