Repository navigation
Releases: kizemo/alpha-file-manager
Release list
Alpha File Manager v3.6.0
3.6.0:删不掉的文件,现在有专门的一条路
Windows 删文件失败时只给你一句话:「操作无法完成,因为文件已在另一程序中打开。」
然后你就卡在那儿了 —— 不知道是谁占着它,也不知道除了关掉那个程序还能怎么办。
这一版把这条路的两个环节都补上了,而且不用额外装任何东西。
第一件:解除文件锁定 —— 先问清楚是谁占着它
新加的「解除文件锁定」会问 Windows 到底哪些程序开着这个文件,把它们连
进程号一起列出来 —— 是编辑器、是备份软件、还是一个卡住的服务,一眼能认出来。
同一个对话框里可以结束其中任何一个,结束完应用会重新探一次,告诉你这个文件
现在删得掉删不掉。
它自己从不删任何东西。 它只把挡路的清掉 —— 只读位、占着文件的程序 ——
然后把「空出来了」这件事告诉你。真正要删文件,那是「彻底删除」的事。
查占用者用的是 Windows 自带的 Restart Manager(rstrtmgr.dll),不需要额外
装任何东西。
第二件:彻底删除 —— 三步递进,每步都如实回报
有些文件怎么试都删不掉:它本身是只读的,或者有个程序开着它、又不允许别人删。
「彻底删除」按代价从低到高试三步:
- 清只读位。 只读文件用普通删除会报「操作无法完成」,去掉只读位往往就删了。
- 标记删除。 文件还被占着的话,把它标记成「等最后一个句柄关掉就删」——
占用程序一放手,文件当场消失,不用重启。 - 登记为重启后删除。 连标记删除都被拒绝(内核态驱动占着、或者文件系统
不认这个操作),就登记给 Windows,让它下次启动时删掉。这一步需要管理员权限。
三步都失败时会如实报错,不会假装文件已经没了。
清只读位时只清只读位,隐藏位与系统位原样保留 —— 清掉隐藏位会让文件在
资源管理器里凭空冒出来,那是副作用,不是本意。
为什么一个外部依赖都没加
调研了 GitHub 上的同类方案:P4suta/restart-manager(Rust 包装,MIT/Apache-2.0,
但只有 2 star、零 fork)、sjp/Sherlock(C#)、mantvmass/file-lock-checker(Rust)、
Process Hacker / System Informer(内核驱动路线)、NirSoft Unlocker 与
Sysinternals handle.exe(闭源,不可嵌入)。
结论是一个都不需要引:
- 本仓已经依赖
windowscrate 0.58,而它的Win32_System_RestartManager模块
已经把 Restart Manager 整套 API 编译进本地 registry 了(RmStartSession/
RmRegisterResources/RmGetList/RmShutdown/RmEndSession),只是
Cargo feature 没开; Win32_Storage_FileSystem里已有SetFileInformationByHandle+
FILE_DISPOSITION_INFO_EX+FILE_DISPOSITION_FLAG_DELETE,这是「标记删除」
的正规做法;Win32_System_Threading里已有OpenProcess/TerminateProcess。
所以这一版只是调用已经躺在依赖树里的 API,Cargo.toml 只多一行 feature。
对比之下 restart-manager 那个 crate 自己也承认它包的就是同一套 API,而它只有
2 star —— 引进来反而多一份要维护的依赖与 MSRV 风险。内核驱动路线则要处理驱动
签名与安全评审,成本与本项目的体量不匹配。
顺带修掉的:仓库在 HEAD 上打包不出来
有一个测试文件用错了 Node 的类型(ReturnType<typeof readdirSync> 取到的是
Buffer 重载),于是 vue-tsc 报 5 条类型错误,tauri build 的
beforeBuildCommand 直接失败 —— 仓库在 main 分支上根本构建不出安装包。
改好之后 vue-tsc --build 完全干净。
这一版是怎么验的
- 算法层与命令层分成两个文件。
file_lock.rs(算法本体)刻意不引用
tauri::AppHandle与tauri::async_runtime::*—— 那是cargo test --lib的
隐形红线(会把 tao 的窗口链拖进测试二进制,进程在加载期以
STATUS_ENTRYPOINT_NOT_FOUND崩掉)。所以有 7 条用例是真的建文件、真的开
句柄、真的调 Win32 API:Restart Manager 真的能查出占用进程、空闲文件查不出
占用者、被独占占用时如实报错不假装成功、解锁成功后文件仍在、只读文件
清位后可删。 - 真实机器上用打包产物验(
tauri build的产物,不是tauri dev—— 本项目
的 dev 构建路由页内容区全空白,界面结论一律作废):右键菜单里两项都在;弹框
列出的占用者与注入的持锁进程 PID 一致;仍被占用时点解锁会如实报「文件仍被
其他程序占用」;结束占用进程后解锁成功且文件仍在;彻底删除能删掉空闲
文件、只读文件与已解锁的文件;对仍被占用的文件会退到「已登记为重启后删除」。 - 门禁:
cargo test --lib809 例全过;vitest243 文件 / 2201 用例全过;
eslint .188 errors 与基线逐条相同(零新增);vue-tsc --build0 错误。
这个版本不是什么
- 不处理远程文件。 服务器上的文件锁不在本机,本地手段对它没有意义,
所以远程条目上根本不出现这两项。 - 不是内核级的解锁器。 占着文件的是内核态驱动时,只能退到「重启后删除」。
- 不支持一次解锁一整棵树。 递归枚举占用者的收益与复杂度不成比例。
- 不新增任何外部依赖。
构建信息
- 版本号:
3.6.0 - 安装包:
Alpha_File_Manager_3.6.0_x64-setup.exe - 大小:20608754 字节
- SHA-256:
a2724ac90bbc4f986af51b5b62a1861c2223316a9733b5fa39930e8fe27d644a
Alpha File Manager v3.5.1
3.5.1: the installer stops claiming someone else's name, and the repository page gets fixed
Summary: The installer now records this project's own publisher instead of the name of the project it was forked from, which is what lets the program be listed in the Windows Package Manager and be upgraded in place. The repository page itself is repaired too: the comparison table between the three file managers is a table again, the licence is the actual GPL-3.0 text so the repository is labelled GPL-3.0 rather than "NOASSERTION", and the automatic winget submission points at this repository's own package id instead of the upstream one.
第一件:安装器里挂的是别人的名字
Windows 的"应用和功能"、以及 Windows 包管理器,认的是安装器写进注册表的那个
Publisher 字段。这个字段是从上游继承下来的 —— 也就是说,你在"应用和功能"里
看到的发布者是上游项目的名字,不是 Alpha File Manager 自己的。
这不只是好不好看的问题。包管理器靠 发布者 + 程序名 + 版本号 三样对上号,才
知道自己装的这份和清单里那一份是同一个程序;对不上,它就认为你机器上装的是
一个"没见过的软件",升级也不会把它认出来。
现在这个字段写的是本项目自己的发布者 kizemo,与 winget 清单里的 Publisher
完全一致。顺带修好的还有一处隐患:源码里有一行注释中间夹了一个裸的换行符
(CR),平时看不出来,但任何编辑器在保存时规范化行尾,都会把那一行劈成两半,
后半句变成裸代码,整个工程直接编译不过 —— 注释被切断这件事,本来就该修。
第二件:仓库页面的表格根本不是表格
README 里那张"三款文件管理器对比"表,表头是五列,下面那行分隔线却只有四段。
GitHub 的 Markdown 解析器遇到这种情况,会把整块当成普通段落 —— 于是页面上
看到的不是表格,是一堆竖线。
原因是当时重写 README 时只按内容写了表头,没按列数对齐分隔行。现在补齐了,
并且加了一条常驻门禁:它会解析仓库里所有 Markdown 文件的表格,逐表核对表头、
分隔行和数据行的列数,不一致就红。门禁自带"故意喂坏输入"的负向用例,保证它
自己还能变红 —— 一道永远绿的检查等于没有检查。
第三件:许可证 GitHub 认不出来
LICENSE.md 之前是一份手写的摘要,不是许可证原文。GitHub 靠匹配许可证原文
来识别协议,匹配不上就在侧栏写 NOASSERTION。现在是 GPL-3.0 的规范原文
(35,149 字节 / 675 行),版权与致谢声明移到新的 NOTICE.md,仓库侧栏显示
GPL-3.0。
第四件:仓库门面重写
README 之前接近 50 KB,大半是一面更新日志墙,把项目本身的介绍挤到了第二屏。
现在它是一份能看完的页面:门面图、徽章、Highlights、五组功能表、下载矩阵,
以及"从源码构建"和社区入口。中文版同步重写。
第五件:自动发布到 winget 的工作流指错了地方
.github/workflows/winget.yml 里还留着上游的包 ID 和上游的安装包文件名规则。
真跑起来,我们的二进制会以"更新上游包"的名义提交上去。现在包 ID 是
kizemo.AlphaFileManager,资产名规则也换成本仓库实际产出的名字。
第六件:包元数据还指向上游
Cargo.toml 的 authors 与 repository、HTTP User-Agent 里写的仓库地址、
Flatpak 的主页与问题反馈链接,全都还是上游项目的。现在都指向本仓库。
Alpha File Manager v3.5.0
English summary
3.5.0 fixes two things: "Compare and Sync" was effectively unusable on real
folders, and the delete progress bar was lying.
- Comparing two folders no longer gives up at the first unreadable directory.
Unreadable directories are skipped, the count is shown in the summary, and the
comparison carries on. Only an unreadable root is still an error. - Comparing a large tree is about fifty times faster. The metadata now comes
straight from the directory entry instead of rebuilding an absolute path, and
four workers collect in parallel. Measured over the same ten thousand entries:
1.18 s before, 23 ms after (measured in both orders, so neither side could
claim a warm cache). - The comparison now reports its progress — which side it is reading, how
many entries it has been through, and how far along the comparison itself is. - Deleting a big folder tree finally shows what it is doing. The progress
bar is driven by the number of items actually deleted, with the freed space
shown alongside. Cancelling is checked before every file, and up to four
independent subtrees are removed in parallel.
3.5.0:比较不再罢工,删大树时进度条终于说实话了
这一版修两件事:「比较并同步」在真实目录上基本用不了,以及批量删除的
进度条在骗人。两件都是用户在实际使用中撞上的,不是设想出来的。
第一件:比较并同步 —— 撞上一个读不了的目录,整个功能就废了
用户反馈的是「进度非常缓慢,最后变成一个报错页面」。查下来是两件事叠在一起。
报错的原因:任何一个读不了的子目录,就让整个比较失败
代码里收集目录树是这样写的:
let read = std::fs::read_dir(&dir_path)
.map_err(|error| format!("无法读取目录「{}」:{error}", dir_path.display()))?;任何一个子目录读不了,整个比较就返回错误。 而 Windows 上读不了的目录
太多了 —— System Volume Information、$RECYCLE.BIN、别人正占着的目录、
权限不足的用户目录。真实目录树上几乎必然有。
我在本机造了一个拒绝访问的目录,复现得很干净:
panicked: collect left: "无法读取目录「…\left\denied」:拒绝访问。 (os error 5)"
所以用户看到的「报错页面」不是什么玄学,是这个功能在真实目录上基本不可用。
现在读不了的目录被跳过,计数报出来(界面上显示「无法读取 N」),比较继续
走其它目录。根目录本身读不了才算真错误 —— 那是真的没法比。
慢的原因:每个条目的元数据查得太贵
收集阶段占了整轮比较的 93% 的时间(实测:收集 4.3 秒,判定 0.11 秒,
序列化 0.17 秒)。而收集慢在每一行代码上:
let Ok(metadata) = std::fs::symlink_metadata(item.path()) else { continue };item.path() 要为每个条目重新拼一次绝对路径,然后再拿这个路径去查一次
元数据。实测这一处就是瓶颈:
| 实现 | 收集 10,020 个条目 |
|---|---|
| 旧写法 | 1.18 秒 |
| 去掉「无条件缓存每个文件的绝对路径」 | 1.44 秒(没改善,不是元凶) |
改用 item.metadata()(目录项自带的元数据) |
35.7 毫秒 |
现在改用 item.metadata()(元数据直接从目录项取),并且四个线程并行收集
—— 这一步是 IO 密集的,单线程会让磁盘的请求队列一直空着。
两个顺序各测一遍(避免「谁先跑谁吃冷缓存」的偏袒):
| 顺序 | 旧实现 | 新实现 | 加速 |
|---|---|---|---|
| 旧→新 | 1.33 秒 | 29.6 毫秒 | 44.95× |
| 新→旧 | 22.9 毫秒 | 1.13 秒 | 49.54× |
一万个条目的目录树,收集一侧现在 23 毫秒;十万个条目的树,旧版要
11 秒,新版约 0.2 秒。
比较的时候终于有进度了
以前比较一棵大树,界面上只有一个转圈 —— 用户分不清它是在干活还是死了。
现在会显示:正在扫描左侧/右侧、已经扫过多少个条目、判定阶段比对了
多少个 / 共多少个。事件里只带结构化数据,文案由界面本地化,17 个语言包
都能说人话。
条目太多时,界面不会再被撑爆
结果树以前是一次性摊平成全部行再逐行渲染。十万个条目就是十万个 DOM
节点,窗口会胀到操作不动。
现在一次只渲染前 2000 行,剩下的按「再显示一批」放出来,并且始终明说
一共多少条 —— 不让用户以为看到的就是全部。统计数字(共多少条、多少有
差异)本来就是全量算的,不受影响;同步计划的计算也在后端自己重新比较,
不受影响。
内容校验和不再把整个文件读进内存
开了「按内容校验和」这一项,以前用 std::fs::read 把每个文件整个读进
内存 —— 几百 MB 的安装包就足以把进程撑爆。现在按 64 KB 的缓冲流式读,
内存占用与文件大小无关;而且摘要和收集一样是并行的。
比较这一块现在也有日志了
以前 compare 模块一行日志都不写,出了问题只能靠猜。现在会记:比较
开始了(两侧路径 + 准则)、每侧收集到多少条目 / 跳过多少 / 耗时多久、
判定结果、总共多少条差异。应用日志在
%LOCALAPPDATA%\com.sigma-file-manager.app\logs\Alpha File Manager.log。
第二件:删大树时进度条终于说实话了,取消也真的能停
这一版修的是批量删除。触发它的是一份 2026-10-22 的分析报告:删一个
25 万文件的目录树,进度条长时间停在 4%,用户判断为「卡死」。
先说结论:删除逻辑一直是对的,没卡死、没死锁、没丢文件。问题出在两处 ——
进度条在骗人,以及删除吞吐偏低。这一版把两处都动了。
先说清楚一件事:报告的归因是错的
报告说「进度按字节计量,所以小文件多的时候失真」。翻代码发现不是这样:
本项目的删除进度一直按顶层路径数推进,字节数从来没进过进度公式。
症状一样(进度条不动),根因不同,修法也不同 —— 不是换计量单位,是得逐条目
数。这一条如果搞错了,改出来的东西看着对、实际还是骗人。
进度条现在按条目数走
删一棵含 25 万文件的目录树,进度条会随着文件一个个被删掉稳定往前走,
不再是「4% 卡 40 分钟」。界面上同时给两个口径,并明确标注:
- 已删除 248,332 / 250,053 项(99.3%) —— 主指标
- 已释放 55.43 GiB / 72.06 GiB(76.9%) —— 辅助指标
统计阶段(刚开工、总数还没数完)走不确定态,不报百分比 ——
给不出「离完成还有多远」时就不该假装能给出。
取消真的能停
以前点「取消」只在顶层路径之间检查,所以删一个大目录时点了取消,
也得等那个目录整个删完才生效。现在每个文件之前都检查一次,
点下去最多再删几十个文件就停。
删之前先量一遍规模
删除开始前先把要删的树走一遍,拿到「N 个文件 / M 个目录 / X GiB」。
这给了进度条一个真实的分母(而不是猜的),也让用户点下删除之前就知道
自己在删什么。超过 1 万个条目时,界面上会直接把规模摆出来。
代价是多走一遍目录树。对机械硬盘来说这是实打实的 I/O,
但换来的「进度条不说谎 + 随时能停」值这个价。
子目录并行删
机械硬盘删海量小文件是寻道瓶颈:磁头一次只能服务一个位置。
单线程串行删的时候,磁盘队列长度长期只有 0.75 —— 磁盘根本没被喂饱。
现在同一目录下的各个子目录分给最多 4 个线程并行删除。几个互不依赖的
子树同时删,磁头才能同时寻道多个位置。
顺带修掉的:安装与更新链路
用户反馈「装完 3.4.0 又装了一次,感觉像是激活了在线更新」。查下来:
- 扩展的更新检查,以前一次都没成功过。 它打的是
github.com/.../tags.atom—— 这个地址在国内网络根本连不通(本机实测:
github.com 直连 20 秒超时,api.github.com 稳定 200)。现在改走
api.github.com(应用自身的更新器早就在用它了),原地址留作兜底。
顺带说明:扩展的更新检查第一次真正能用。 - 更新检查与应用器都有日志了。 更新检查每次都记下:装的是哪个版本、
服务器报的是哪个版本、哪个源答的、判定了有没有更新、报了什么错。
安装器会写一份安装日志(%TEMP%\alpha-file-manager-install.log):本次装的
版本、检测到的既有安装版本与位置、这次是不是同版本重装、最终选定的
安装目录、四个阶段各自的结论。
这一版是怎么验的
- 比较引擎的回归测试直接复现了那个报错:造一个拒绝访问的目录,
断言比较继续而不是失败,断言读不到的条目数被报出来。 - 性能是量出来的,不是估的:旧实现照抄进基准里,和新实现在同一批文件上
对照,两个顺序各测一遍。 - 删除核心(
delete_tree.rs)刻意不引用 tauri,所以算法本体有单测:
计数、字节口径、取消的及时性、并行删除的完整性、进度单调性、节流闸门。 - 跨语言契约门禁: Rust 的进度事件字段与 TS 的接口逐条对得上
(写错一个字母,两边单测照样全绿,真机上进度条就成了 0% 到底)。 - 真实机器上用打包产物验:删除进度随条目推进、取消立刻生效、并行删除不留残渣。
这个版本不是什么
- 没有 ETA。 速率外推在机械硬盘上抖动很大,给一个看似精确的数字反而不如不给。
- 比较结果仍然是「先全部算完再显示」。 这一版做的是不撑爆界面,
没有改成边算边出。 - 没有内容校验和、没有镜像模式。 与 3.4.0 同。
- 没有超过阈值时的二次确认框。 规模已经摆出来了,但「再问一次才动手」
这个交互这版没做。
构建信息
- 版本号:
3.5.0 - 安装包:
Alpha_File_Manager_3.5.0_x64-setup.exe - 大小:20494128 字节
- SHA-256:
76f3a5957c4626378e1de53cafc1ca56331cfb689c163c14e168afe45f895ef4
Alpha File Manager v3.4.0
3.4.0:左右两格能对比了,判不准的绝不乱动
3.4.0 加了两个东西:并排比较两个目录并按结果同步,以及侧边栏里的
「添加网络驱动器」入口。前者是这个 fork 目前最大的一块新功能。
如果你之前在 3.3.0,这一版不需要任何操作 —— 它是纯增量,没有改动既有行为。
先说清楚这个功能不做什么
它永远不删东西。 同步会补上缺失的文件、更新更旧的那一份;只在目标侧存在的
东西会被报告出来,而不是删掉。想做「镜像」(两边完全一致,多出来的删掉),
留到后面的版本。
这是刻意的。比较目录这个动作本身就容易搞错方向,一旦带上删除,一次误判就是
不可逆的数据损失。第一版先把「看清楚」和「动手」分开。
并排比较
把导航器分成左右两格,工具栏上就多一个「比较并同步」按钮。点开是三步:
第一步,设置。 左右两侧要比的目录(默认取两格当前所在的位置)、比较准则、
排除规则。
准则是这样生效的,顺序照抄 WinSCP:
- 先看修改时间。时间不一样就按时间判,大小根本不看。
- 时间一样,再看文件大小。
- 还一样,再看内容校验和。
- 一个准则都不勾,判据就是「两边都有这个文件」—— 于是只报出真正新增的条目。
还有一档「区分大小写」,给那些会改名字大小写的服务器用。
排除规则一行一条,支持 * 和 ?。命中的目录整棵子树都不参与比较。
第二步,结果。 一棵差异树,加上统计条与状态筛选。
树而不是平铺列表是有意的:整个子目录只在一侧存在时,它应该显示成一个子树,
而不是一堆没有上下文的散名字。状态分九种 —— 相同、仅左侧、仅右侧、左侧较新、
左侧较旧、大小不同、内容不同、类型不同、无法判定。
第三步,预览与执行。 先给你看清单:将要新建哪些目录、复制哪些文件、跳过哪些。
看完再点「开始同步」。同步在后台跑,有进度条,随时能取消;失败的条目单独列出来。
判不准的时候,它会直说
这是这一版最要紧的一条设计。
两个文件时间戳一样、内容不同,是最难办的一种情况:左边那份并不比右边旧,
可它们又不是同一个文件。这种情况下自动同步必然有一边被覆盖掉,而且覆盖的是
哪个,取决于实现里的某个隐含约定。
Alpha File Manager 把这类标成**「方向待定」**,原样放着。它们会被单独列在
「跳过」里,等你自己决定。不自动覆盖。
同样的处理适用于「一边是目录、一边是文件」这种结构冲突 —— 那时候目标侧根本没有
落脚点,硬做只会产生一堆必然失败的错误。
侧边栏里的「添加网络驱动器」
侧边栏底部的盘符列表末尾,多了一个虚线框的按钮 —— 添加网络驱动器。
这就是 Windows 资源管理器给了很多年的那个入口,也是你真正会去找它的位置:
盘符多了、或者想临时挂一个共享的时候,从那儿点一下最顺。
选共享、选盘符(留空则由 Windows 自动分配),挂上之后盘符就出现在侧边栏里,
跟别的盘一样。协议在 Windows 上只列 SMB —— sshfs 要装 WinFSP、nfs 要开
Windows 的功能,摆出来点一下必然失败,不做那种「摆出来再说」的事。
顺带修掉的一个真问题
映射网络驱动器之后,应用报出来的盘符多半是空的。原因是它在 Windows
net use 的输出里找 "assigned" 这个词 —— 而 Windows 真正打印的内容里
根本没有这个词(本机实测输出是「Drive Z: is now connected to ...」)。
盘符明明挂上了,报出来的却是空的。
现在改成直接问 Windows:哪个盘符指向那个共享。这跟 Windows 的语言、
输出表格的列宽、以及远程路径里带不带空格都无关。
这一版是怎么验的
每一项都在装机包上量过,不是在开发构建上:
- 比较并同步跑通完整一轮:自造左右两棵目录树(靶子全部自造,不用用户真实目录),
比较 → 看差异树 → 看预览清单 → 执行 → 核对落盘结果。 - 「方向待定」这一档单独验过:造两个时间戳相同、内容不同的文件,确认它们
没有被覆盖,而是进了跳过清单。 - 网络驱动器映射:自建 SMB 共享 → 侧边栏点「添加网络驱动器」→ 挂载 →
盘符出现在侧边栏 → 卸载 → 复原现场。 - 「取消」单独验过:把靶子放大到 3.84 GB,同步传到一半点「取消」,
确认文件数停在原地不再增长,报告里标注「已取消」。
这个版本不是什么
- 不含删除、不含镜像。 见上。
- 不含内容校验和的远程比对。
RemoteProvider没有 checksum 的概念,FTP 也没有
标准校验和命令。开了校验和准则而有一侧是远程时,结果会如实标成「无法判定」,
而不是假装两边一样。阶段 A 的界面也不暴露这个开关。 - 不含断点续传、不含导出清单。 计划里的三期排期里,这些在阶段 C。
完整清单见更新日志。
构建信息
- 版本号:
3.4.0 - 安装包:
Alpha_File_Manager_3.4.0_x64-setup.exe - 大小:20455261 字节
- SHA-256:
f85d160ab207cb01ffe9efa1c225d9ef1f3c61b914f146da8ad78afc4dcc534c
Alpha File Manager v3.3.0
3.3.0:文件能拖到别的程序里去了,而且不挡路
3.3.0 是 3.3 系列的第一个正式版。它把四轮从未单独发布过的 beta 收进了一个包 ——
扩展加固、键盘连选、背景混合模式、长按拖拽 —— 外加从 beta 转正式这一步。
如果你之前在 3.2.12-beta 上,这一版包含了一路准备成 3.2.13、3.2.14、3.2.15、3.2.16
的全部内容。中间不需要装两次,也不需要做任何操作。
按住文件,直接拖到别的程序里
在文件或目录上按住不放,过一会儿就会起一次真正的 Windows 拖拽。把它拖到微信、
钉钉、浏览器,松手就行。
这件事要用起来,有三件事必须同时成立:
- 你按下的时候,窗口不会跳到最前层。 Windows 平常是一按下鼠标就把窗口带到前面,
于是你伸手去够后台窗口里的文件时,那个窗口立刻就把你要放进去的程序盖住了。
按住不放的时候,Alpha File Manager 待在原地。 - 你拖到哪个程序,那个程序就提到前面来。 拖着文件走的时候,鼠标停在哪个应用上,
那个窗口就替你带到前面 —— 往微信、钉钉的对话里发附件时,对话窗口就在眼前,落点也看得见。 - 松手之后不会把前台抢回来。 拖拽结束时前台留在原处,你放进去的那个程序继续待在前面,
接着就能用。
普通单击的行为一点没变:在后台窗口里点文件,窗口照样跳到前面、照样拿到键盘焦点。
只有「按住」这个手势会把窗口按住不让它抢。按住的时候鼠标只要动一点点,这个手势
就变成普通拖拽 —— 一直用老方式拖文件的人完全不受影响。
背景效果,像 Photoshop 一样混合
效果层 —— 铺在应用后面的那层模糊、带颗粒的底色 —— 现在可以按熟悉的图层模式与界面叠加:
变暗、正片叠底、颜色加深、变亮、滤色、颜色减淡、线性减淡(添加)、叠加、柔光、强光、
差值、排除、颜色、明度。菜单按 Photoshop 的方式分组,WebView 实际上画不出来的模式
会被直接藏起来,而不是摆在那里让你选了却没反应。
除「正常」以外的每种模式还可以指定跟什么混合。保持「界面」时,效果和窗口下层混合,
跟以前一模一样;切到「填充色」,效果就跟你挑的颜色混合 —— 八种现成色板,或者你自己
取一个颜色。
鼠标在菜单上往下移,背后的页面会实时预览那个模式;离开菜单时你保存的模式会被放回去。
用键盘连选
在目录里,你按下的那个条目成为锚点;之后每按一次 Shift+方向键都从锚点扩展选择范围,
往回按则把范围收回来。不按 Shift 的普通方向键仍然只移动到下一个条目、只选中它,跟以前一样。
扩展再也不能被引到你自己的内网
抓扩展时,现在检查的是它实际连上去的那个地址 —— 而不是纸面上写下来的那个名字。
落在私有网段、本机回环地址或者保留地址里,下载会被拒绝,并把拒绝的理由如实报出来。
检查发生在连接的那一刻,所以首次请求、重试、备用镜像、跳转链上的每一跳都算数。
扩展能不能运行一个程序,现在由它自己的描述文件说了算 —— 应用从磁盘上读这份文件,
在里面没写明要这项权限,程序就不会被允许启动。冒用别的扩展的身份来问,或者根本不问,
都会被拒绝。
那个「沙箱」没了,因为它本来就不是沙箱:扩展代码本来就跑在别处 —— 自己的 worker,
或者沙箱化的 iframe —— 真正的隔离来自那里。
还修了这些
- 网络盘上的文件可能在你不知情时被永久删除。 回收站只存在于本地磁盘。以前这一步
只是失败,文件照样被删掉 —— 一个字都不说。现在会先问,只有你点头才永久删除。 - 窗口回来时底边可能落在屏幕外。 现在窗口分阶段恢复,再收进工作区,总能回到你
够得着的地方。 - 双击顶栏不能最大化窗口。 顶栏上那块空白此前不是真正的拖拽区。现在它就是了。
- 最大化按钮可能让窗口同时处于全屏与最大化。 现在按钮先退出全屏再最大化。
- 文件列表重排之后,长按仍可能把窗口带到前面。 「指针是否停在可拖拽条目上」改为
按指针实际所在的位置判断,列表重排不再改变答案。 - 外观设置里的颜色选择器不再被藏起来。 选了「与填充色混合」之后,色板与自定义取色器
始终露出来。
这一版是怎么验的
每一项都在装机包上量过,不是在开发构建上:
- 长按拖出分四个场景实测:普通点击(阳性对照)、拖拽悬停目标、快速点击(不许误起
出站拖拽、UI 线程不许卡死)、长按拖到资源管理器(文件必须真的落盘)。判据一律读
GetForegroundWindow()的句柄与应用日志,不靠肉眼。 - 拖拽期间目标窗口确实被提到前面,放手后前台留在目标程序,Alpha File Manager
没有把前台抢回来。 - 外观设置的色板与自定义取色器截图确认,并且由你手动确认过点自定义色块能打开
系统取色器。
这个版本不是什么
- 扩展自己的网络请求仍然没有这一层防护。 扩展要访问哪个地址,现在仍然只靠它自己
的描述文件里写的白名单兜底。本轮没有扩到这里 —— 因为一刀切会误伤「连自己本机小服务」
这种正当用法。要收紧的话得换个思路。 - FTP 和 FTPS 依旧没有真机验过。 承自 3.2.11。
- 长按拖出目前只验过 Windows。 这个 fork 的打包产物走的是 NSIS,Linux 侧未做验证。
完整清单见更新日志。
构建信息
- 版本号:
3.3.0 - 安装包:
Alpha_File_Manager_3.3.0_x64-setup.exe - 大小:20407375 字节
- SHA-256:
cc932bfae9c517c6239ef70887a4279b57d72712144b378a74b8135bd25a8d9b
Alpha File Manager v3.2.12-beta
3.2.12-beta:远程目录能写了
3.2.11 让远程服务器「能看」,这一版让它能改:在服务器上新建目录,给远程的文件和目录改名。
SFTP、FTP、FTPS 三种协议都接上了。
这一版是 beta —— 功能在真机(SFTP)上验过,但还没攒够一轮使用反馈,细节可能再调。
远程能新建目录了
在远程那格按 Ctrl+Shift+N,或者用菜单里的「新建目录」,填个名字,服务器上就多一个目录。
失败时服务器怎么拒绝就怎么报,名字框不关,方便你改对再试。
远程的文件和目录能改名了
选中一个远程条目按 F2,名字就变成可编辑的。改的是原目录里的名字,不是把它挪到别处 ——
挪动是另一件事,这一版还没有。
SFTP 走的是标准的 SSH 改名命令:目标名字已经被占了就失败,不会悄悄把你已有的那个文件顶掉。
目录改名之后,里面的东西跟着一起走。
「新建文件」在远程目录里彻底没有
远程服务器上新建空文件这件事永远不做 —— SFTP 没有「创建」这条命令,FTP 的「上传」也得先有
一个本地文件。所以远程目录里那个入口整个消失:菜单里没有,工具栏里没有,按 Ctrl+Shift+M
也不会再弹出一个注定失败的对话框 —— 那样只会让人白填一遍名字才发现不行。现在按下去直接告诉你
「远程目录不支持新建空文件」。
这一版是怎么验的
这一版每一项都在装机包上、对着一台真实 SFTP 服务器量过,不是在开发构建上:
- 远程改名:改完之后用 SSH 独立复核 —— 新名字在、里面的文件跟着搬过去了、旧名字没了,
而且修改时间没变(说明是改名,不是「删了重建」)。 - 远程新建目录:SSH 复核远程真的多出这个目录;同时确认本地那一格没有被误建。
- 远程没有「新建文件」:本地按快捷键照常弹窗(证明快捷键本身是通的),远程按同一个快捷键
不弹窗、直接给提示;远程的「⋯」菜单里也确实没有那一项。 - 顺带把上一版的远程删除也重跑了一遍:空目录能删,非空目录被服务器如实拒绝。
这个版本不是什么
- 远程跨目录移动没有。 改名只在原目录内。
- 远程批量改名没有。 一个一个来。
- FTP 和 FTPS 的这两个功能没有真机验过。 真机只有 SFTP;FTP 走的是另一条通道,
有测试覆盖,但没有对着真的 FTP 服务器跑过。 - 写操作断了线不会自动重做。 连接中途断开就是失败并如实上报 ——
重试分不清「服务器压根没收到」和「服务器做了、只是回执丢了」,
而建出两个同名目录、或者把同一个东西改两次名,比给一句错误提示糟糕得多。
完整清单见更新日志。
构建信息
- 版本号:
3.2.12-beta - 安装包:
Alpha_File_Manager_3.2.12-beta_x64-setup.exe - 大小:20346038 字节
- SHA-256:
39e9224822e8c51260dc29e934ad19c69faf360148dea989318f6f6be83179d2
Alpha File Manager v3.2.11
3.2.11:能真正浏览远程服务器了
3.2.11 是 3.2 系列里第一个能真正浏览远程服务器的正式版。3.2.5 到 3.2.11 这七轮的工作
合在一起发布:SFTP、FTP、FTPS 连接真的会列出远程目录,目录树跟着你走进去,两格能一起
浏览,能上传、能下载、能删除远程文件 —— 上面还压着一批本地修复。
远程服务器,是真的
三种协议,各一条代码路径:SFTP、FTP、FTPS。保存下来的连接不再只是一条书签,
打开它就会列出远程目录,连同文件、大小和日期。
第一次连上一台机器时,你会先看到一个指纹确认框,确认之前什么都不信任。SSH 公钥与
X.509 证书按同一台主机和端口分开存放,信任其中一个不代表信任另一个;证书变了会明确
报成「证书已变更」,而不是一个含糊的网络错误。所有记住过的主机都列在设置 → 已信任主机,
随时可以撤销。
目录树跟着你走进远程目录
切到远程面板,目录树就变成远程那棵树:以你给这条连接配的目录为根,用连接名标注。
它会展开到你所在的那一层,把那行滚到眼前,并且跟着你真正在用的那一格走 —— 远程机器
还在建连时,另一格抢不走高亮。
树本身也修了一串:只留一个根(不再自己冒出额外的根)、滚到你正在用的目录、重建出来的
空节点会清掉「已读」记录(否则远程树会展开却永远是空的)。
两格一起浏览
给连接配一个起始路径,打开时落在那里而不是远程根目录。打开同步浏览,两格就一起走:
在本地进入 wp-content,远程那格也进 wp-content;往上退一级,另一格也跟着一退。
上传、下载 —— 以及自己刷新的那一格
把文件或整个目录传到远程那侧,或者从远程拉回来。传输一结束,收到东西的那一格会重新
读一次自己的目录,新文件立刻就在,不用等你手动刷新。刷的是它自己,而且只在它还
显示着收到文件的那个目录时才刷。
远程文件也能删了
远程文件原来完全没有删除入口。现在有了 —— 只给一个**「删除」,不给「移至垃圾箱」
这种根本做不到的选项,因为远程服务器上没有回收箱。删之前会先说清楚,而且你的账户要是
没权限,服务器怎么拒绝就怎么报。菜单项永远不隐藏**:前端判不准你在服务器上是属主、
属组还是其他人。
目录必须先清空 —— 两种协议都不支持递归删除,目录里还有东西时服务器会拒绝,提示会
直接告诉你「先清空这个目录」。
权限从列表里挑
给远程文件设权限原来要自己敲八进制,而敲错一位就是悄悄放宽或收紧了别人对这个文件的
访问。现在是一个常用模式的下拉,每一项都带着 rwxr-xr-x 形式。文件当前那个权限
一定在列表里,所以打开对话框、什么都不改、直接应用,等于什么都没改。
本地这边:新标签页打开「位置」,能看出盘用了多少
点 + 原来落在用户文件夹,现在落在**「位置」页。每张分区卡片按已用比例填充,
分三档强弱;列表视图里「大小」右边多了一列「可用空间」**。
「位置」页不再有修改时间和创建时间两列 —— 磁盘既没有修改时间也没有创建时间,
那两列整列都是横杠,占着宽度什么都不说。换到别的目录,反过来去掉的是「可用空间」列,
理由一模一样。
几个小修
- 工具栏那个垃圾桶图标原来浮出来的是悬停提示,点不着。现在是真正的菜单,每一项旁边
还标着快捷键(Del/Shift+Del)。 - 已保存的连接列表现在在启动时、窗口显示之前就会读完。以前**「权限设置」**入口和树根上
的连接名会安安静静地不工作,直到你恰好去过一个会加载这份列表的界面。 - 「大小」这一格的标题原来会渲染两遍(「大小 ⓘ大小」),三支互斥之后只出现一次。
这个版本不是什么
- 向远程复制目前没有实现。 上传和下载是各自独立的入口,它们是能用的;跨本机与远程
之间的复制、剪切、粘贴,给远程条目改名,以及在远程目录里新建文件或目录 —— 这些还没有。 - FTPS 的文件内容目前还是明文。 控制通道有证书固定保护,但数据通道仍用服务端默认行为,
也就是文件内容在链路上是明文。RFC 2228 的PBSZ/PROT P没有发。 - FTPS 从来没有连过真实服务器。 SFTP 有。
这一版是怎么验的
3.2.11 那一轮的东西都是在打包产物上量的,不是在开发构建上:上传文件、上传目录、
下载文件,都对着一台真实 SFTP 服务器看接收的那一格自己刷新。
前几轮(3.2.5 ~ 3.2.10)是靠单测与故障注入覆盖的,每一条都先写出会坏掉就红的测试,
再故意把它弄坏,确认测试真的会红。它们没有逐条在装机版上验过,这一版也不声称验过。
完整清单见更新日志。
构建信息
- 版本号:
3.2.11 - 安装包:
Alpha_File_Manager_3.2.11_x64-setup.exe - 大小:20304867 字节
- SHA-256:
df6f451bd2615511867f4ffc51047bfc9a53127b7002a66247da2568cdc7fa6b
Alpha File Manager v3.2.4
3.2.4:3.2 系列的第一个正式版
地址栏终于按资源管理器的方式工作了,分屏可以把两格对调,缩略图大小在窗口变窄时
也找得到了。它取代 3.2.1-beta —— 那是上一个对外发布过的测试版。
地址栏:粘一条路径,按回车就进去
点一下地址栏,它就原地变成输入框,当前路径整条选中。粘一条新路径按回车,
直接进那个地方。以前光标落在末尾,粘贴会追加在旧路径后面,拼出一个
「旧路径 + 新路径」的诡异结果;想在原路径后面续写,按一下 End 就行 ——
资源管理器也是这么做的。
这里一并修了三个缺陷,任何一个单独存在都足以让「粘一条路径」变得不可靠:
- 只有末尾带斜杠的路径才被当成目录。 粘
D:\photos\2026(不带结尾斜杠),
回来的会是一条搜索结果,而不是那个文件夹本身。像photos这样的裸词仍然
按名字搜,按名称查找的行为没有变化。 - 回车不再等列表刷新。 刚粘完的一小段时间里,候选列表还没刷新好,这时候
按回车以前是什么都不做。现在直接以输入框里的内容为准,立刻生效。 - 方向键仍然优先。 你用方向键选中了某个文件再按回车,打开的仍然是那个
文件 —— 输入框里的路径不会覆盖你的选择。
候选列表读起来是一棵小树
第一行就是你正指向的目标目录:顶格、字重更重,打开时就选中,按回车直接进去。
子目录和文件统一缩进一格、彼此齐平,左侧一根竖线串下来,每行一条短横线指向图标,
最后一行收尾。目录排在文件前面,各自按名称排序。
分屏两格可以左右互换
开着两格时,每格工具栏的搜索框右侧会出现一个左右互换按钮。两边都拖到位之后,
想把左边那个换回左边,点一下就行:左边刚才显示的,右边开始显示,反之亦然。
只换文件夹 —— 两格各自的窗口宽度、以及在标签组里的先后顺序都保持不变。
只有一格时按钮不出现,因为没有另一格可换。两格本来就开着同一个文件夹时什么也不会
发生,这是刻意的:交换两个一模一样的文件夹本就没有意义,让面板闪一下一个你看不见的
变化反而更让人困惑。
窄窗口下也找得到缩略图大小
窗口宽度不足 600px 时,工具栏会折叠成一个「⋯」菜单,里面是返回、前进、向上、
位置、刷新、列表/网格切换,以及新建目录、新建文件。
缩略图大小此前只加在宽屏那排图标上,从没有在折叠菜单里做过一份 —— 所以窗口
一收窄,这个功能就等于消失了,不是藏得深,是真的没有。现在两处都有,顺序也对齐:
宽屏上排在视图切换按钮之后,「⋯」菜单里排在同名的那一项之后,两处打开的是
同一个弹窗。
这个版本是什么
3.2.4 是 3.2 系列的第一个正式构建。3.2.1-beta 引入的 MCP 服务原样保留,
仍然只有只读能力 —— 本版本没有任何功能能移动、改名或删除你的文件。
想回退或关闭 MCP?把「设置 → 实验性功能 → MCP 服务」关掉即可,服务端不留驻、
不联网。
构建信息
- 版本号:
3.2.4 - 安装包:
Alpha_File_Manager_3.2.4_x64-setup.exe - 大小:19178095 字节
- SHA-256:
5c6bfce83daba440676dedb95331f60de70383cab1b95dd6d16a450a8ad884a8
Alpha File Manager v3.2.1-beta
文件管理器可以被 AI 助手指挥了
Alpha File Manager 现在内置了一台 MCP 服务端。MCP(Model Context Protocol)是
Claude、Codex、Cursor 等助手本来就会说的一种通用接口。在「设置 → 实验性功能」里
打开开关并选好权限档位,这些助手就能通过一套标准接口读取你的盘符、浏览目录、
搜索文件 —— 走的是已经认识快捷方式、虚拟目录和网络共享的那个文件管理器,
而不是靠截图去猜你的文件摆在哪。
先说清楚它现在能做什么、不能做什么
6 个工具,全部只读:
- 列出盘符(含卷标与剩余空间)
- 列出可移动设备(U 盘、网络共享)
- 浏览你指定的目录
- 按文件名搜索(可搜整盘索引,也可限定在某个目录子树内)
- 计算目录大小(含子目录,最慢的情况封顶两分钟)
- 读取你的收藏分类与条目
移动、改名、复制、删除 —— 一个都做不到。写操作不是「默认关着」,是根本没实现,
代码里就没有。这个测试版的定位就是先把读取这条链路做扎实。
三道防护,一道都不能关
- 只监听本机。 服务只绑定 127.0.0.1,局域网里别的设备即使知道地址也连不上。
- 随机访问密钥。 第一次打开服务时生成一串四段式密钥,没有它的请求一律拒绝。
- 拒绝陌生网址发来的请求。 只接受来自本机地址的访问 —— 防止你浏览器里的某个
网页偷偷去连这个服务。
四个权限档位(关闭 / 只读 / 可写 / 每次审批),默认是关闭,服务根本不启动。
而且不管你选哪一档,每次调用都会重新查一遍 —— 把档位调低,下一次请求立刻生效,
不用重连。
一键装进各家助手,不用手抄配置
过去要把 AI 助手接进来,得自己去翻它的配置文件、手抄一段 JSON —— 最容易出的错
就是少一个逗号,而助手的反应只是「没有配置任何服务」,什么线索都不给你。
现在设置页会列出本机上能识别到的助手,写明每一家的配置文件放在哪,一键写好;
同一个界面也能一键移除。已支持:Codex、Cursor、Claude Code、Claude Desktop、
OpenClaw、Minimax Code。
因为改的是你自己的配置文件,写入严格守三条规矩:
- 只合并,不重写。 先解析文件,只增删那一个条目,再写回 —— 文件里别处的设置,
包括 Codexconfig.toml里的注释,都保持原样。 - 读不懂就不写。 解析失败的文件原封不动并明确报错,而不是替换成一份看起来对、
其实不是的内容。 - 每次写之前先备份,存成
<原文件名>.alpha-mcp.bak。
配置写完之后需要重启对应的助手才会生效,所以面板上会常驻一条提示,写明改了哪个
文件、备份放在哪里。
谁问过什么,都会记下来
每次调用都写进应用设置目录旁边的纯文本日志:调用的是哪个工具、时间、是放行还是
拒绝。想核对助手都干了什么,用记事本打开就行。
这是测试版,请注意
- 权限档位里的**「可写」目前是预留的**,选了也不会有写操作发生。
- 配置面板在正式版前仍可能调整;各语言的界面文案也未必都已定稿。
- 想回退?把「设置 → 实验性功能 → MCP 服务」关掉即可,服务端不留驻、不联网。
构建信息
- 版本号:
3.2.1-beta - 安装包:
Alpha_File_Manager_3.2.1-beta_x64-setup.exe - 大小:19158990 字节
- SHA-256:
45a743b46a882f9fbfb9093e632ce47a7d1ebd867544e227c26fed383182f142
Alpha File Manager v3.1.3
目录内搜索:递归搜索此前确实没生效
这一版最要紧的一处修复,由两个互相独立的原因叠在一起造成 —— 只修其中一个的话,在大多数目录里仍然是搜不到深层文件。
第一处:遍历上限数错了对象。
递归遍历有一个「扫够就收工」的安全阀,但它数的是扫过的条目数,不是命中的条目数;而这个上限又是「结果条数上限」的 20 倍(默认 50 × 20 = 1000)。于是在一个 43,167 个条目的照片目录里,遍历到第 1000 个条目就收工了 —— 表现和「只搜当前层」一模一样。现在改成按命中数收工,扫描量用的安全阀单独放宽,两者不再互相牵制。
第二处:短查询的命中被评分门槛丢掉了。
文件名子串命中之后还有一道分数门槛,而三位数字的查询门槛高达 0.9。搜 095 命中 20251009_0095_27.jpg 的得分只有 0.82,于是当场被丢弃。这与目录大小无关,小目录也一样搜不到。现在分数只用于排序,不再当门槛 —— 先确认是子串命中,再让分数去管「谁排在前面」。
因此 3.1.2 更新日志里「目录内搜索已递归化」那句话,当时并不成立。给你带来困扰的是我们,不是你的用法。
搜索选项从弹窗搬到结果正上方
显示文件 / 显示目录 / 精确匹配 / 拼写容错 / 结果条数上限,此前收在过滤框里的一个按钮加弹窗中 —— 而调这些选项的目的恰恰是看着结果变,藏在弹窗里每调一次都要开合一次浮层。
现在它们常驻显示在搜索结果上方,改一个勾就能一直看着列表更新。非搜索状态下不显示,不占地方。
拼写容错这次是真做了实现,不是摆设:目录内递归搜索在子串没命中时会再算一次相似度。关闭时拼错的查询依然搜不到,开启才会命中 —— 两个方向都有测试守着。
目录内搜索与全局搜索现在用的是同一套选项,不再各说各话。
搜索后分屏:左边保持目录,右边是搜索
此前打开全局搜索会把搜索界面顶到左边、目录被挤到右边。现在反过来:左侧保持目录视图,右侧切到搜索界面,与「打开所属目录」的布局一致。单格模式下没有左右之分,保持原样。
搜索深度默认 7 层 → 9 层
已有安装会通过数据迁移一并改成 9 层 —— 只改默认值对已经装机的用户无效,因为他们本地的设置里已经写着 7。你自己手动调过的深度不会被覆盖。
右键「添加到收藏」增加分类选择
右键收藏一个文件或文件夹时,现在会先让你选分类:可以选已有的,也可以当场新建一个。没有输入框,就是挑一个。新分类名与已有分类重名时会落到「未分类」而不会中断操作;已经收藏过的条目会直接跳过,不再重复问。
这一版以修复搜索与打磨交互为主,没有引入新的设置项或破坏性改动。如果你此前遇到过「在当前目录搜子目录里的文件搜不到」,这一版就是为那个问题做的。
构建信息
- 版本号:
3.1.3 - 安装包:
Alpha_File_Manager_3.1.3_x64-setup.exe - 大小:18234977 字节
- SHA-256:
b96c494574df982a174a5d1cd0f198d18492bd1fbdcbc69b6415e0b0e033b31d