Files
ProjectAGiPrompt/35-黑苹果DELL/2-工作电脑备份/7-数据同步备份-高级解决方案-实施方案.md
2026-06-24 17:20:42 +08:00

58 KiB
Raw Blame History

两台 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/wddls /c/Users/wdd 人工确认实际挂载路径,二选一固定,不要混用。

0.3 上线顺序

  1. 做台式机目标目录备份和空间检查。
  2. 配置笔记本 WSL2 SSH 客户端、台式机 WSL2 rsync 运行时、Windows OpenSSH 免密登录。
  3. 关闭两端微信,先做 rsync dry-run。
  4. 执行一次微信 rsync 首次灌入。
  5. 安装并配对两端 Syncthing。
  6. 先上线微信目录同步并观察。
  7. 再上线 Git 项目目录同步并观察。
  8. 最后上线少量开发工具配置同步。
  9. 配置 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 退出码 07 都表示复制层面可接受;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 退出码 07 为可接受。


2. Phase 1Windows 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

预期结果:至少有一个发行版,且 VERSION2

如果看到 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 foundrsync: 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 准备。处理步骤:

  1. 回到 Task 6a在台式机安装 WSL2 和 rsync。
  2. 在笔记本 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"
  1. 看到 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/cWindows 文件系统不接受 WSL 的 chgrp。处理方式:

  1. 不需要手动修改这些目标文件。
  2. 暂停当前脚本或等待其结束都可以;如果已经传了很多文件,重新运行修正后的脚本会增量续传。
  3. 确认 ~/sync-scripts/wechat_initial_sync.sh 的 rsync 参数中已经包含:
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
  1. 语法检查:
bash -n ~/sync-scripts/wechat_initial_sync.sh
  1. 重新执行:
~/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 上可能无法设置。处理方式:

  1. 确认 ~/sync-scripts/wechat_initial_sync.sh 的 rsync 参数中已经包含:
--omit-dir-times \
  1. 同时保留前面的 Windows 元数据规避参数:
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
  1. 语法检查并重新执行:
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。完整解决步骤:

  1. 不删除台式机 C:\Users\wdd\xwechat_files,保留已经传过去的 36GB 数据。
  2. ~/sync-scripts/wechat_initial_sync.sh 中的 rsync 起始行从 rsync -avz \ 改为:
rsync -rvz \
  1. 确认参数包含以下完整 Windows-safe 参数组:
--partial \
--inplace \
--whole-file \
--delete \
--size-only \
--no-owner \
--no-group \
--no-perms \
--no-times \
--omit-dir-times \
  1. 确认脚本中不再出现 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 没有输出。
  1. 重新执行一次收敛同步:
~/sync-scripts/wechat_initial_sync.sh

预期结果:

  • 因为已经传过 36GB第二次主要做增量检查和少量补齐。
  • 不再出现 failed to set times
  • 最终退出状态为 0
  1. 如果仍然出现 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按以下顺序处理

  1. 确认 Windows 网络配置为专用网络。
  2. 确认防火墙允许 C:\Tools\Syncthing\syncthing.exe
  3. 确认两机在同一局域网。
  4. 重新启动 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 显示 SyncingScanningOut 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 OFFguard 行被移除。

  • 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 5Git 项目仓库 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 22Git 项目同步验收

操作位置: 两台机器。

  • 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 23Git 日常使用规则

  • 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 1JetBrains IDE 启用 Settings Sync

在 IntelliJ IDEA、WebStorm 或其他 JetBrains IDE 中打开:

File -> Settings -> Settings Sync

登录同一个 JetBrains 账号,启用同步。

  • Step 2VS 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 7Syncthing 自启动与运行参数

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 仓库中:

  1. 打开原文件和 *.sync-conflict-* 文件。
  2. 使用 IDE diff 工具比较内容。
  3. 把需要保留的内容合并到原文件。
  4. 删除 *.sync-conflict-* 文件。
  5. 执行:
git status
git diff
git add -A
git commit -m "fix: resolve syncthing conflict"
  • Step 3处理微信冲突文件

微信数据冲突不要手动改数据库文件。处理规则:

  1. 如果冲突文件是图片、视频、语音等媒体文件,保留较新的或两者都保留。
  2. 如果冲突文件是数据库文件,先停止两端微信和 Syncthing。
  3. .stversions 中找出最近正常版本。
  4. 复制出备份后,再决定恢复哪一份。
  5. 不确定时,不删除任何数据库冲突文件。

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 手动扫描 APIhttps://docs.syncthing.net/rest/db-scan-post.html