Uninote
Uninote
用户根目录
brdr
common
programming
docs
tests
后端试题
问题讨论

可以把这个现象拆成 两套 Undo 机制叠加 来理解:VS Code 自己维护文件操作的撤销记录,同时 Windows Explorer/Windows Shell 对“移入回收站”这类文件操作也有自己的撤销能力。

1. VS Code 删除文件时,并不只是简单调用 DeleteFile

当你在 VS Code Explorer 中删除文件,并选择“Move to Recycle Bin”时,大致流程是:

VS Code Explorer
      │
      │ Delete
      ▼
VS Code 文件操作层
      │
      ├── 记录一次 Workspace File Operation
      │      delete: xxx/test.txt
      │
      └── 调用系统 Trash / Recycle Bin
                    │
                    ▼
             Windows Shell
                    │
                    ▼
               Recycle Bin

VS Code 自己知道:

“刚才用户从 D:\project\test.txt 删除了一个文件。”

因此,当你随后在 VS Code 文件树中执行 Undo(Ctrl+Z)时,它可以执行一个与删除对应的恢复操作。

这就是为什么 VS Code 自己能够 Undo 文件删除。

需要注意的是,这和编辑器文本的 Ctrl+Z 不是完全同一个层面的东西。VS Code 有专门针对文件创建、删除、移动、重命名等资源操作的 Undo/Redo 管理。


2. 为什么 Explorer 也能撤销这次删除?

这里更有意思。

关键点不是 VS Code 把自己的 Undo Stack 分享给了 Explorer,而是:

VS Code 删除文件时使用了 Windows 提供的 Shell/Recycle Bin 文件操作机制。

Windows Shell 本身知道:

D:\project\test.txt
        ↓
Recycle Bin

这次操作属于 Windows Shell 可以追踪/恢复的文件操作。

所以你打开 Windows Explorer,在对应目录执行:

Ctrl + Z

Explorer 可以出现类似:

Undo Delete

然后 Windows 从回收站恢复:

Recycle Bin
      ↓
D:\project\test.txt

因此实际上存在两个不同层次:

层次 谁维护 用途
VS Code Undo VS Code 撤销文件创建、删除、移动、重命名等
Windows Shell Undo Windows Shell / Explorer 撤销 Delete / Move / Rename 等 Shell 文件操作

它们不是共享同一个 Undo Stack。


3. VS Code 在 Windows 上是怎么把文件送进回收站的?

现代 VS Code 的文件系统实现经过多次演进,所以具体内部调用链要以对应版本源码为准;但从架构上看,它不是把文件内容复制到某个 VS Code 临时目录,然后让 Explorer 知道这件事。

核心操作是:

VS Code
  │
  │ trash(file)
  ▼
Electron / Node / native integration
  │
  ▼
Windows Shell recycle-bin mechanism
  │
  ▼
$Recycle.Bin

Windows 的回收站也不只是:

MoveFile("a.txt", "C:\\$Recycle.Bin\\xxx")

这么简单。

Windows 会保存恢复文件所需要的元数据,例如原始路径等。现代 Windows 的 $Recycle.Bin 中通常能看到成对的数据,例如:

$Rxxxxxx.txt
$Ixxxxxx.txt

大致可以理解为:

$Rxxxxxx.txt
    实际被删除的数据

$Ixxxxxx.txt
    原文件信息
    ├── 原始路径
    ├── 文件大小
    └── 删除时间

所以系统知道:

$Recycle.Bin\$RABCDEF.txt
             │
             │ restore
             ▼
D:\project\src\test.txt

应该恢复到哪里。


4. Explorer 为什么知道“刚才 VS Code 删除了这个文件”?

这里需要区分两个概念。

Explorer 并不是读取:

VS Code Undo Stack

而是依赖 Windows Shell 的文件操作/回收站机制和 Shell 状态。

也就是说,类似:

VS Code
 └─ Delete foo.cpp
       │
       ▼
 Windows Shell operation
       │
       ├─ Recycle Bin metadata
       └─ Shell operation state

Explorer
       │
       └─ Undo Delete
              │
              ▼
       Windows Shell restore

因此这个 Undo 能够跨应用表现出来。

这也是最值得注意的一点:

“Explorer 能撤销 VS Code 的删除”主要是 Windows Shell 能力,而不是 VS Code 实现了一个跨进程 Undo 协议。


5. 为什么直接 DeleteFileW() 往往没有这种效果?

假设自己写 C++:

DeleteFileW(L"D:\\project\\test.txt");

这基本就是:

Application
     │
     ▼
NTFS 删除文件

没有:

Recycle Bin
Shell File Operation
Undo information

所以 Explorer 通常无法:

Ctrl+Z → Undo Delete

因为文件本身已经真正删除了。

如果要实现类似 Explorer/VS Code 的体验,在 Windows 原生程序中,更接近的思路是使用 Windows Shell 的文件操作接口,而不是裸 DeleteFileW。

现代 Windows 主要可以研究 IFileOperation;老代码里经常会看到 SHFileOperation。例如 IFileOperation 可以表达:

DeleteItem
MoveItem
CopyItem
RenameItem

并让 Shell 参与整个文件操作。


6. 一个很容易混淆的地方

可以做一个实验:

VS Code:
    delete a.txt
        ↓
Windows Explorer:
    Ctrl+Z
        ↓
a.txt 恢复

此时 VS Code 的文件监控器会收到文件系统变化:

FileWatcher
     │
     ▼
a.txt created

所以 VS Code Explorer 又会看到 a.txt。

这里不是:

Explorer
    ↓
通知 VS Code:
“我执行了你的 Undo”

而更像:

Explorer
    ↓
Windows 恢复 a.txt
    ↓
Filesystem change
    ↓
VS Code FileWatcher
    ↓
刷新 Explorer Tree

这与 VS Code 自己执行 Undo 是两条不同的路径。


7. 整体架构可以理解成这样

                     ┌──────────────────────┐
                     │      VS Code         │
                     │                      │
                     │ Explorer             │
                     │ File Operation Undo  │
                     └──────────┬───────────┘
                                │
                         delete / trash
                                │
                                ▼
                    ┌───────────────────────┐
                    │ Windows Shell / OS    │
                    │ File Operation        │
                    └──────────┬────────────┘
                               │
                               ▼
                       ┌──────────────┐
                       │ Recycle Bin  │
                       │              │
                       │ $R... data   │
                       │ $I... meta   │
                       └──────────────┘
                               ▲
                               │
                     Explorer Ctrl+Z
                               │
                    ┌──────────┴────────────┐
                    │ Windows Explorer      │
                    └───────────────────────┘

因此你观察到的现象实际上说明了两个事实:

VS Code Ctrl+Z 能恢复

VS Code 自己记录文件操作
        +
利用系统 Trash/Recycle Bin 恢复

而 Explorer Ctrl+Z 也能恢复

删除本身进入了 Windows Shell / Recycle Bin 的文件操作体系

二者最终都作用于同一个真实文件系统,因此任何一方恢复文件,另一方都能通过文件监控看到变化。

如果你是想在自己的 C#/C++ 文件树组件里实现与 VS Code 完全类似的“删除 → VS Code/Explorer 都可以 Ctrl+Z”行为,重点应该继续研究 Windows 的 IFileOperation、Shell Undo 与 Explorer 的 undo state。这部分比单纯调用回收站 API 更关键。

axios

diff

点赞(0) 阅读(19) 举报
目录
标题