Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions plugins/unlock/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ release/
# Preload binaries downloaded at install time (handle.exe + its EULA)
public/preload/handle.exe
public/preload/handle-EULA.txt

# witr optional diagnostic binary (npm postinstall / runtime extract)
public/preload/tools/witr.exe
# runtime extract destination is %LOCALAPPDATA%/unlock-file/tools (not in repo)
26 changes: 25 additions & 1 deletion plugins/unlock/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
# Changelog

## 1.1.0 - 2026-09-30

### 修复

- **重启管理器兜底检测完全失效**:`RmGetList` 的 `pnProcInfoNeeded`(out) 与 `pnProcInfo`(ref) 传入了同一个变量,计数被写回清零,导致分配 0 字节缓冲区、永远查不到占用者;异常还被空 `catch` 吞掉,所以一直静默失败。现在两者使用不同变量,失败会输出到 stderr 并记入运行记录。
- **一个文件被多个进程占用时漏报**:witr 匹配到多个目标时退出码为 4,输出的是一份人类可读列表(不是 JSON),此前被当作"无占用者"。现在会解析出全部 PID,并逐个用 `witr --pid` 补全启动链。
- **重启管理器结构体越界写内存**:`RM_PROCESS_INFO` 按 Ansi 计算大小,而 `RmGetList` 按 `WCHAR[256]/WCHAR[64]` 写入,缓冲区被写穿导致 PowerShell 宿主堆损坏(`0xC0000374`;1 个占用者侥幸不崩,2 个以上必崩)。结构体解析改到 C# 内完成,并显式标注 `CharSet.Unicode`。
- **路径特殊字符**:生成的 PowerShell 脚本改为单引号字面量并转义 `'`,路径中含 `$`、反引号、双引号时不再被当成变量或破坏脚本(此前可造成脚本错误甚至命令注入)。

### 新增

- **结束进程后闭环验证**:结束占用进程后轮询探测(约 1.8s)文件能否重新独占打开,只有确认解除才提示成功;仍被占用时明确提示"可能还有其他程序或系统服务在访问",并刷新剩余占用者列表。端口检测同样会复查端口是否释放。
- **一键结束全部占用进程**(文件与端口)并统一验证结果。
- **占用状态四态探测**:被占用 / 可独占打开 / 文件夹 / 路径不存在。文件夹被占用(很常见的工作目录占用)会给出可执行的排查建议,不再只显示"无法确认锁定状态"。
- 权限不足与文件被占用分别提示,不再混为一谈、不再误入"查找占用进程"流程。

### 改进

- 前端提示改为**成功 / 提示 / 注意 / 错误**四级提示条,全部口语化文案:不再出现"退出码"、"engine="、"PID xxx 仍然存活"等调试字眼;需要排查时可展开底部"运行记录"。
- 进程卡片文案中文化:`Why It Exists` → "它是怎么跑起来的"、`Source` → "来源"、`Working Dir` → "工作目录"、`kill` → "结束进程"。
- 进程卡片展示 Windows 服务短名,并提示"直接结束可能触发服务自动重启,建议先停止该服务"。
- 占用者名称解析为真实进程名(此前重启管理器可能只给出单个字母,如 `W`)。
- 新增 preload 接口与文案的回归测试:重启管理器检测、双占用者端到端、闭环验证、占用状态探测、提示文案不含调试字眼、preload 暴露的接口齐全(75 个用例全绿)。测试串行执行,并改为"等占用真的建立"再断言,消除竞态导致的偶发失败。
- witr 仍为可选依赖:首次运行时自动释放/下载,不可用时由 Windows 重启管理器接管检测,功能不受影响。

## 1.0.0 - 2026-07-13

- 初次发布,将插件提交至 ZTools 插件仓库。
- 实现 Windows 文件占用检测与进程结束功能,支持文件和目录拖入。
- 增加文件删除/粉碎、端口占用查询及对应操作页面。
- 完善中文路径、权限与失败提示,修复 PowerShell 脚本和检测结果解析问题。
- 统一为 Windows 专用实现,完善发布时所需工具与依赖。
- 统一为 Windows 专用实现,完善发布时所需工具与依赖。
58 changes: 50 additions & 8 deletions plugins/unlock/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# 解除占用

ZTools 插件 — 解除文件占用、粉碎文件、检测端口占用。仅支持 Windows。
ZTools 插件 — 用 **witr 式因果溯源**解释「谁在占用 / 为什么在跑」,再附加 **kill** 解除占用。另附文件粉碎、端口检测。仅支持 Windows。

## 使用方式

### 关键字启动

在 ZTools 搜索框输入:

| 关键字 | 功能 |
|---|---|
| `解除占用` | 打开解除占用标签页 |
Expand All @@ -18,19 +16,63 @@ ZTools 插件 — 解除文件占用、粉碎文件、检测端口占用。仅

将文件或目录拖到 ZTools 搜索框,选择「解除占用」即可直接带入路径并自动扫描。

## 诊断思路(对齐 witr)

```text
文件/端口
↓ 确证持有者(witr --file / 重启管理器,不用 cmdline 猜测)
PID
↓ 溯源解释它为什么在运行(启动链 + 来源)
启动链: explorer.exe (1) → pwsh.exe (20) → node.exe (80)
来源: 交互式 Shell · pwsh.exe
↓ 用户确认后再附加动作
结束进程 / 粉碎
↓ 闭环验证:文件能重新独占打开才算真的解除
已解除占用 / 仍被占用(并列出剩余占用者)
```

- **先解释,再动手**:进程卡片展示「它是怎么跑起来的」启动链与来源(服务 / Shell / 计划任务…),结束进程是附加操作。
- **只确证,不猜测**:占用者来自重启管理器或 witr;不再用命令行子串 / 「可疑 java·node」启发式误报。
- **双引擎溯源**:优先调用 [witr](https://github.com/pranshuparmar/witr)(`--pid --json`);未安装时回退到原生 PowerShell 祖先链 + Windows 服务识别。
- **结束后闭环验证**:结束进程后轮询探测文件是否已能独占打开,只在确认解除后才提示成功;仍被占用时会告诉你还剩谁在占用。
- **提示分级、说人话**:成功 / 提示 / 注意 / 错误四级提示条;不暴露退出码、`engine=` 之类的调试字眼,需要排查时可展开底部「运行记录」。

## 功能

### 解除占用

检测哪些进程正在占用文件或目录,支持一键结束。

检测哪些进程正在占用文件或目录,展示启动链与来源,支持单个或一键结束。结束时自动重启管理器句柄检测 + 结束后独占打开验证:只有确认解除才会提示成功,否则会指出「可能还有谁在占用」。

### 文件粉碎

安全删除文件或目录,粉碎模式会先用随机数据覆写再删除。

安全删除文件或目录,粉碎模式会先用随机数据覆写再删除。占用时弹出确认,展示占用进程后可结束并重试;权限不足与文件被占用会分别提示,避免误以为是占用问题。

### 端口检测

查看指定端口的监听进程,支持一键结束。
查看指定端口的监听进程及启动链,支持一键结束。结束进程后会复查端口是否已释放,被其他进程接管时会明确提示。

## 可选依赖:witr(自动安装)

[witr](https://github.com/pranshuparmar/witr) 用于完整溯源(服务描述、容器、警告等),**会自动安装**:

1. `npm install` 时 postinstall 就绪 `public/preload/tools/witr.exe`(打包进插件作内置副本)
2. 运行时若在 `.asar` 内,会**自动释放**到真实路径 `%LOCALAPPDATA%\unlock-file\tools\witr.exe`(asar 内无法 `spawn`,直接跑会 ENOENT)
3. 内置副本不可用时自动从 GitHub 下载,失败再回退 `winget install PranshuParmar.witr`
4. 全部失败时使用原生 PowerShell 溯源,插件功能不受影响

手动强制重装:

```powershell
node scripts/install-witr.js --force
```

## 开发

```powershell
npm install # 可选:下载 witr
npm run dev
npm run build
npm test # node --test --test-concurrency=1 public/preload/*.test.js
```

测试覆盖:占用者检测(witr 与重启管理器双路径)、占用状态探测、结束后闭环验证、提示文案(不出现退出码等调试字眼)以及前端依赖的 preload 接口是否齐全。
7 changes: 5 additions & 2 deletions plugins/unlock/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"name": "unlock-file",
"version": "1.0.0",
"version": "1.1.0",
"description": "解除文件占用,以方便修改删除文件",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build"
"build": "vue-tsc && vite build",
"postinstall": "node scripts/install-witr.js",
"install-witr": "node scripts/install-witr.js",
"test": "node --test --test-concurrency=1 public/preload/*.test.js"
},
"dependencies": {
"vue": "^3.5.13"
Expand Down
4 changes: 2 additions & 2 deletions plugins/unlock/public/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"title": "解除占用",
"description": "解除文件占用、粉碎文件、检测端口占用,支持拖拽文件和手动输入路径",
"author": "Taitres",
"homepage": "https://github.com/Taitres",
"version": "1.0.0",
"homepage": "https://github.com/Taitres/unlock",
"version": "1.1.0",
"main": "index.html",
"preload": "preload/services.js",
"logo": "logo.png",
Expand Down
Loading
Loading