---
name: environment-cleanup
version: 1.1.0
description: "系统环境整理与磁盘清理。预检磁盘空间→备份环境变量→扫描软件→评估风险→逐项授权迁移→验证→决定是否删除备份→输出 HTML 报告。触发词：整理环境、清理环境、迁移环境、环境整理、磁盘清理、软件迁移。"
category: system-administration
tags: [environment, cleanup, migration, disk, registry, html-report]
---

# 环境整理与磁盘清理

## Overview

对当前 Windows 系统进行环境整理。**预检磁盘空间 → 备份环境变量 → 扫描软件 → 评估风险 → 逐项授权迁移 → 验证 → 决定是否删除备份 → 输出 HTML 报告。**

**核心原则：**
1. **预检优先**：磁盘空间检查在一切操作之前，空间不足则提前中止，不进入后续流程
2. **逐项授权**：所有迁移/清理操作必须逐项获取用户授权，不得批量执行
3. **备份安全**：迁移成功且验证无误后，由用户决定是否删除备份；备份失败时由用户决定是否跳过备份继续

## When to Use

- 用户说"整理环境"、"清理环境"、"迁移环境"
- 用户说"清理磁盘"、"磁盘整理"、"C盘清理"
- 用户说"软件迁移"、"迁移软件"、"把XX迁移到D盘"
- 用户想了解系统安装了哪些软件、哪些可以清理/迁移

## 执行流程（7 阶段）

### 阶段 0：磁盘空间预检（最先执行，不可跳过）

**在任何扫描、备份、迁移之前，先检查磁盘空间。空间不足则提前中止，不进入后续阶段。**

1. 询问用户目标盘符（默认 D:）
2. 获取目标盘总容量、已用空间、剩余空间
3. 快速估算 C 盘可迁移软件总大小（仅扫描路径和 `EstimatedSize`，不深入扫描）
4. 计算所需空间 = 软件总大小 × 1.1（10% 安全余量）

**判断逻辑：**
```
如果 目标盘剩余空间 >= 所需空间:
    → 空间充足，继续阶段 1
    → 输出: "D 盘剩余 XX GB，待迁移 XX GB，空间充足 ✅"
否则:
    → 空间不足，输出差额，询问用户:
       1. 按空间大小排序，选择部分迁移
       2. 迁移到其他盘符
       3. 清理不用的全局包（npm/pip 等）
       4. 保持现状，中止流程
    → **不得进入阶段 1**
```

**输出格式：**
```
=== 磁盘空间预检 ===
目标盘: D:
D 盘总容量: XX GB
D 盘剩余: XX GB
C 盘可迁移估算: XX GB
所需空间 (含余量): XX GB
判定: ✅ 空间充足 / ❌ 空间不足 (差额 XX GB)
```

### 阶段 1：环境变量备份

**在任何迁移操作之前，先备份当前环境变量。**

1. 创建备份目录：`C:\Users\<user>\env_backup_<timestamp>\`
2. 备份内容：
   - `system_path.txt` — 系统 PATH
   - `user_path.txt` — 用户 PATH
   - `system_vars.json` — 所有系统环境变量
   - `user_vars.json` — 所有用户环境变量
3. 验证备份文件存在且非空

**备份失败处理：**
- 如果备份目录创建失败（磁盘空间不足等），询问用户：
  1. **跳过备份，继续迁移**（用户承担风险）
  2. **中止流程，先解决备份问题**
- 用户选择跳过备份时，报告中必须记录"备份已跳过"

### 阶段 2：全量扫描

扫描系统中所有已安装软件，包括：

1. **注册表安装的软件**（HKLM + HKCU Uninstall）
   - 读取 `DisplayName`、`DisplayVersion`、`InstallLocation`、`EstimatedSize`、`Publisher`、`SystemComponent`、`WindowsInstaller`、`UninstallString`
2. **非注册表安装的工具**（手动放置、绿色软件、开发工具）
   - 扫描 `C:\` 根目录、`C:\Users\<user>\` 下的开发工具目录
   - 扫描 `C:\ProgramData\` 下的工具
3. **环境变量依赖**
   - 系统 PATH + 用户 PATH 中的所有条目
   - 所有系统/用户环境变量（JAVA_HOME、NVM_HOME、PYENV 等）
4. **其他盘符已迁移的软件**（用于报告完整性）

**输出格式：每个软件一行**
```
名称 | 版本 | 路径 | 大小 | 系统组件 | 安装方式 | 可迁移
```

### 阶段 3：风险评估

对每个软件进行多维度风险评估：

| 维度 | 检查内容 | 风险等级 |
|------|----------|----------|
| **服务依赖** | 是否有 Windows 服务正在运行 | 有 Running 服务 → 🔴 不可迁移 |
| **注册表深度** | 注册表项数量和深度 | >50 项 → 🔴，10-50 项 → 🟡，<10 项 → 🟢 |
| **环境变量** | 依赖的环境变量数量 | >3 个 → 🟡，≤3 个 → 🟢 |
| **文件关联** | 是否注册了文件类型关联 | 有 .docx/.xlsx 等关联 → 🔴 |
| **MSI 安装** | 是否通过 Windows Installer 安装 | 是 → 🟡（需更新注册表） |
| **系统组件** | SystemComponent 标记 | 是 → ❌ 不可迁移 |
| **安装来源** | InstallSource 是否存在 | 已删除 → 🟡 |

**不可迁移标记条件（满足任一即标记为不可迁移）：**
- `SystemComponent = 1`
- 有正在运行的 Windows 服务且属于该软件
- 系统关键组件（Edge、WebView2、Intel 驱动等）

**高风险标记条件：**
- 注册表 >50 项
- 有文件关联
- 环境变量 >3 个
- 包管理器（Chocolatey、pip、npm 等）

### 阶段 4：逐项授权执行

**每个软件的迁移/清理操作必须单独获取用户授权。**

#### 4.1 迁移前探测（必须在授权前完成）

对每个待迁移软件，**必须先完成完整探测**，列出所有需要迁移后同步的内容：

**A. 环境变量探测：**
```
检查清单：
1. 系统 PATH 中包含该软件路径的条目 → 逐条列出
2. 用户 PATH 中包含该软件路径的条目 → 逐条列出
3. 系统/用户自定义变量中值包含该软件路径的变量 → 逐个列出
   （如 JAVA_HOME、NVM_HOME、TESSDATA_PREFIX、PYENV 等）
4. PATHEXT 中是否有该软件注册的扩展名（如 .py、.pyw）
5. 该软件是否通过快捷方式/启动项引用了自身路径
```

**B. 注册表探测：**
```
检查清单：
1. HKLM/HKCU\...\Uninstall 中的 InstallLocation → 列出
2. HKLM/HKCU\...\Uninstall 中的 UninstallString → 列出
3. HKLM/HKCU\...\Uninstall 中的 InstallSource → 列出
4. 软件自身注册表键（如 HKLM\Software\Git、HKLM\Software\JavaSoft）→ 列出路径
5. 文件关联（HKCR\.ext\shell\open\command）→ 列出
6. COM/DCOM 注册 → 列出
7. 右键菜单扩展 → 列出
```

**C. 服务探测：**
```
检查清单：
1. Get-WmiObject Win32_Service | Where PathName 包含该软件路径 → 列出服务名、状态、启动类型
2. 服务的依赖关系（DependentServices / ServicesDependedOn）
```

**D. 文件关联探测：**
```
检查清单：
1. cmd /c assoc 检查相关扩展名的关联
2. cmd /c ftype 检查关联的打开命令
3. 默认程序注册（HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts）
```

#### 4.2 授权展示（完整清单）

探测完成后，**必须将完整清单展示给用户**，不得隐藏任何依赖：

```
## 第 N 项：迁移 XXX → Y 盘

| 项目 | 详情 |
|------|------|
| 当前路径 | C:\... |
| 目标路径 | D:\... |
| 大小 | XX MB |
| 风险等级 | 🟢低 / 🟡中 / 🔴高 |

### 环境变量依赖（共 X 项）
| 变量名 | 作用域 | 当前值 | 需改为 |
|--------|--------|--------|--------|
| PATH | 系统 | C:\XX\bin | D:\XX\bin |
| JAVA_HOME | 系统 | C:\Program Files\Java\jdk1.8 | D:\Java\jdk1.8 |
| ... | | | |

### 注册表依赖（共 X 项）
| 注册表路径 | 键名 | 当前值 | 需改为 |
|------------|------|--------|--------|
| HKLM\...\GitForWindows | InstallPath | C:\Program Files\Git | D:\Git |
| ... | | | |

### 服务依赖
| 服务名 | 状态 | 路径 |
|--------|------|------|
| 无 / 有（列出） | | |

### 文件关联
| 扩展名 | 关联程序 |
|--------|----------|
| 无 / .py → Python / ... | |

执行计划：
1. 复制目录到目标路径
2. 验证文件数和大小一致
3. 更新环境变量（逐条同步）
4. 更新注册表（逐项同步）
5. 更新文件关联（如有）
6. 删除旧目录
7. 全面验证（执行主程序 + 检查所有变量 + 检查注册表）

[授权询问]
```

#### 4.3 执行步骤（逐项同步，不可省略）

**每个软件必须按以下步骤严格执行，每步完成后再进入下一步：**

**Step 1 — 复制**
```
Copy-Item -Path "源" -Destination "目标" -Recurse -Force
```

**Step 2 — 验证文件**
```
对比源和目标的：
- 文件数量（必须一致）
- 总大小（必须一致）
- 关键文件存在性（主程序、DLL、配置文件）
```

**Step 3 — 同步环境变量（逐条更新，逐条验证）**
```
必须更新的内容（按探测清单逐条执行）：
1. 系统 PATH 中包含旧路径的条目 → 替换为新路径
2. 用户 PATH 中包含旧路径的条目 → 替换为新路径
3. 所有自定义变量（JAVA_HOME、NVM_HOME 等）→ 更新值
4. PATHEXT（如有新增扩展名）→ 更新

更新后必须立即验证：
- 读取更新后的变量值，确认新路径正确
- 确认旧路径已完全替换，无残留
```

**Step 4 — 同步注册表（逐项更新，逐项验证）**
```
必须更新的内容（按探测清单逐条执行）：
1. InstallLocation → 新路径
2. UninstallString → 新路径（含引号和参数）
3. InstallSource → 新路径（如存在）
4. 软件自身注册表键中的路径值 → 逐个更新
5. 文件关联中的路径 → 更新
6. COM/DCOM 注册路径 → 更新

更新后必须立即验证：
- 读取更新后的注册表值，确认新路径正确
- 确认旧路径已完全替换，无残留
```

**Step 5 — 删除旧目录**
```
降级策略：
1. Remove-Item -Recurse -Force
2. 检查占用进程 → Stop-Process → 重试删除
3. regsvr32 /u 反注册 DLL → 重试删除
4. Rename-Item 重命名为 _old → 提示用户重启后手动删除
```

**Step 6 — 迁移后全面验证**
```
必须验证的内容（全部通过才算完成）：
1. 主程序可执行 → 运行 --version 或 --help
2. 环境变量 → 逐个读取并确认值正确
3. 注册表 → 逐个读取并确认值正确
4. PATH → 确认新路径存在且可访问
5. 文件关联 → 测试关联文件能否正确打开
6. 依赖工具 → 测试该软件的子命令/插件是否正常

验证失败处理：
- 环境变量未更新 → 立即修复
- 注册表未更新 → 立即修复
- 主程序无法执行 → 回滚并报告原因
```

**删除旧目录的降级策略：**
```
1. Remove-Item -Recurse -Force
2. 检查占用进程 → Stop-Process → 重试删除
3. regsvr32 /u 反注册 DLL → 重试删除
4. Rename-Item 重命名为 _old → 提示用户重启后手动删除
```

### 阶段 5：结果验证

所有迁移操作完成后，进行全局验证：

1. **PATH 验证**：读取系统和用户 PATH，检查每个条目是否存在
2. **环境变量验证**：检查所有非 PATH 环境变量指向的路径是否存在
3. **幽灵路径检测**：找出 PATH 中不存在的条目
4. **重复条目检测**：找出 PATH 中的重复条目
5. **软件可用性验证**：尝试执行每个已迁移软件的主程序

### 阶段 6：备份处理 + 输出报告

**迁移成功且验证无误后，询问用户是否删除备份：**

```
所有迁移已完成，验证通过。
备份目录: C:\Users\<user>\env_backup_<timestamp>\
是否删除备份？
  1. 保留备份（推荐，便于后续回滚）
  2. 删除备份（释放 XX KB 空间）
```

使用 [`references/report-template.html`](references/report-template.html) 模板生成可观测性报告，保存到用户桌面。

**报告必须包含以下章节：**

1. **概览统计**：已迁移数、跳过数、释放空间、幽灵路径清理数、环境变量修复数、验证通过率
2. **迁移结果明细表**：每个软件的名称、大小、操作、环境变量、注册表、验证状态
3. **环境变量清理记录**：旧值 → 新值对照表
4. **当前 PATH 状态**：系统 PATH + 用户 PATH 完整列表，已迁移条目标记
5. **不可迁移软件**：软件名、大小、原因、服务信息
6. **跳过的软件**：软件名、大小、风险、跳过原因
7. **目标盘已迁移软件现状**：路径、大小、状态
8. **磁盘空间对比**：迁移前 vs 迁移后
9. **安全提醒**：备份位置（或"已跳过"/"已删除"）、回滚方法、生效提示

## 安全约束

- **磁盘空间预检必须最先执行**，空间不足则提前中止，不进入后续任何阶段
- **环境变量备份必须在迁移之前完成**，备份失败时由用户决定是否跳过
- **所有迁移操作必须逐项获取用户授权**，不得批量执行
- **备份保留至用户明确决定删除**，迁移成功且验证无误后才询问
- **不得删除用户文件**，旧目录删除失败时重命名兜底
- **不得修改系统关键组件**（Edge、WebView2、驱动等）
- **有 Running 服务的软件不得直接迁移**，必须询问用户是否停止服务
- **HTML 报告必须保存到用户桌面**，不得覆盖已有报告
- **环境变量修改后提示用户重启终端生效**
- **备份目录路径必须在报告中记录**，便于回滚

## 回滚方法

如果迁移后出现问题：

1. 从备份目录 `C:\Users\<user>\env_backup_<timestamp>\` 恢复环境变量
2. 将 D 盘的新目录复制回 C 盘原路径
3. 重启终端/资源管理器

备份文件说明：
- `system_path.txt` — 迁移前的系统 PATH
- `user_path.txt` — 迁移前的用户 PATH
- `system_vars.json` — 迁移前的所有系统变量
- `user_vars.json` — 迁移前的所有用户变量
