environment-cleanup · v1.1.0 · 2026-09-15 · sha256 85c60fb1d11c6604

environment-cleanup v1.1.0A

Immutable. This exact content is served forever at /api/v1/blob/85c60fb1d11c6604.

---
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` — 迁移前的所有用户变量