Windows 文件自动整理工具 —— 监控你指定的文件夹(如 Downloads、桌面),新文件"就绪"后按分类在"门文件夹"(默认
D:\magicdoor)内自动创建指向源文件的软链接。源文件始终原位不动,绝不移动/复制。
日常下载的文件经常散落在 Downloads、桌面等位置,需要手动按类型归类。传统"文件整理工具"会移动或复制文件,导致:
- 下载器(浏览器/迅雷/qBittorrent)正在写入的文件被误处理;
- 源文件被挪走后,原路径的程序引用全部失效。
魔法门换了一种思路:源文件永远不动,只在门文件夹里创建指向源文件的软链接(符号链接),并按扩展名自动分类。这样:
- 你的文件仍然在原来位置,所有引用不失效;
- 门文件夹成为一个"分类视图",按 图片/文档/视频/程序/压缩包 分门别类;
- 链接几乎不占磁盘空间(零数据块),批量整理毫无压力。
| 功能 | 说明 |
|---|---|
| 🗂️ 自动分类建链 | 监控文件夹出现新文件 → 等待写入完成(就绪检测)→ 按扩展名分类 → 在门文件夹创建软链接 |
| ⚡ 批量并发提速 | 多文件并行处理(默认并发 4,可配置),大批量复制时显著提速(实测 8 文件约 0.6s) |
| 📁 存量文件整理 | 可选:添加监控路径后自动扫描并整理该路径下已有的存量文件 |
| 🔄 重命名自动处理 | 源文件重命名后自动删除旧链接、创建新链接,无需重启 |
| 🗑️ 源文件删除实时清理 | 源文件删除时,门文件夹中指向它的链接立即删除(含整个源目录删除场景) |
| 🔗 断链启动清理 | 每次启动自动扫描并删除指向不存在目标的失效链接(只删链接,绝不碰用户手动放置的真实文件) |
| 🔄 门链接同步源文件(可选) | 门文件夹内删除/重命名软链接时,可同步删除/重命名其指向的源文件(删除需确认框,危险操作) |
| ♻️ 缺失链接恢复 | 源文件还在但链接被误删时,一键恢复缺失链接(主界面按钮)或启动时自动恢复(设置开关) |
| 🚀 开机自启动 | 设置面板勾选后注册到 Windows 开机自启动(当前用户级,无需管理员),取消即移除,启动时自动校验修复 |
| 勾选后每次启动自动开始监控文件夹,无需手动点"启动"(随开机自启一起实现无人值守) | |
| 👁️ 源文件隐藏(可选) | 为源文件设置"系统+隐藏"双属性,使其在资源管理器中不可见;随时可取消恢复 |
| 🛡️ 就绪检测 | 独占打开(ReadWrite + Share.None)确认文件写入完成,配合长度稳定二次确认,兼容各类下载器 |
| 🪟 GUI + 系统托盘 | 主界面管理监控列表/门路径/启停/状态灯/滚动日志;最小化到托盘常驻,托盘菜单退出 |
| 🔒 单实例 | 重复启动自动静默退出,不会多开 |
| ⚙️ 设置面板 | 分组布局 + 参数说明 + 即时校验 + 恢复默认,所见即所得 |
| 📂 分类规则可视化编辑 | 内置 5 类默认规则,可在设置中编辑分类名称与扩展名列表(保存到 categories.json,重启生效) |
| 🔄 Pending 补偿队列 | 建链失败/超时的文件自动记入待处理队列,重启后自动重试(最多 3 次),防丢链 |
| 🚀 提权引导 | 权限不足时提示以管理员身份重启;拒绝提权后降级为"仅记录"模式,不反复弹窗 |
下载 MagicDoor.exe(self-contained 单文件,无需安装 .NET,Windows 10/11 64 位直接双击运行)。
符号链接创建需要管理员权限或开发者模式。非管理员首次运行会在建链时弹出提权提示。
# 需要 .NET 8 SDK
dotnet run --project src\MagicDoor- 启动程序:双击
MagicDoor.exe,出现主界面(默认门路径D:\magicdoor)。 - 设置门文件夹:主界面"门文件夹"输入框可直接填写或点"浏览..."选择(默认
D:\magicdoor,程序会自动创建)。 - 添加监控文件夹:点"添加",选择要监控的目录(如
C:\Users\xxx\Downloads、桌面),可添加多个。 - 启动监控:点"启动",状态灯变绿,开始监听新文件。
- 查看结果:向监控文件夹下载/复制文件,稍等片刻,门文件夹下会自动出现对应分类的软链接。
- 日常使用:程序常驻系统托盘;关闭主窗口只是隐藏,托盘右键"退出"才真正退出。
- (可选)整理已有文件:在设置中勾选"添加路径时自动整理已有文件",重新添加监控路径即可一次性整理该路径下已有的全部文件。
- (可选)恢复缺失链接:若门文件夹中链接被误删(源文件还在),点门文件夹旁的"恢复缺失链接"按钮即可重建;或在设置中开启"启动时自动恢复缺失链接"。
- (可选)链接同步源文件:在设置中开启"重命名/删除门文件夹链接时同步源文件",即可在门文件夹直接操作链接来反向管理源文件(删除同步为危险操作,会弹确认框)。
| 分组 | 设置项 | 说明 |
|---|---|---|
| 监控处理 | 并发处理数 | 同时处理文件的最大数量,批量复制提速(默认 4),修改后下次启动生效 |
| 按扩展名二级分类 | 开启后分类下再按扩展名建子目录(如 文档\pdf\),修改后即时生效(下一次建链即按新布局) |
|
| 隐藏源文件 | 为源文件设置"系统+隐藏"属性,勾选/取消即时生效 | |
| 添加路径时自动整理已有文件 | 添加监控路径后自动扫描并整理该路径下已有的存量文件 | |
| 删除门文件夹链接时同步删除源文件 | 危险操作:删除门文件夹中的软链接时,同步删除其指向的源文件(删除前需确认框) | |
| 重命名门文件夹链接时同步重命名源文件 | 重命名门文件夹中的软链接时,同步重命名其指向的源文件 | |
| 启动时自动恢复缺失链接 | 启动时检查并恢复监控文件夹中源文件对应的缺失链接 | |
| 开机自启动 | 注册到 Windows 开机自启动(当前用户级,无需管理员),点确定即生效 | |
| 启动时自动开始监控 | 启动后自动开始监控监控文件夹,无需手动点启动 | |
| 编辑分类规则… | 打开分类规则编辑窗口,可增删分类、修改名称与扩展名列表 | |
| 就绪检测 | 就绪检测超时(秒) | 文件等待就绪的最长时间,超时进入待处理队列(默认 60s) |
| 就绪检测重试间隔(毫秒) | 检测到占用后的重试间隔(默认 500ms) | |
| 稳定确认等待(毫秒) | 二次长度稳定确认等待,0 表示禁用(默认 500ms) | |
| 日志 | 日志保留天数 | 启动时自动清理过期日志文件(默认 30 天) |
数字输入支持即时校验:非法输入实时红框 + 中文错误提示,无需等点"确定"才发现。右下角"恢复默认"一键还原全部默认值。
内置默认分类(可在设置 → "编辑分类规则…"中自定义,保存后下次启动生效):
| 分类 | 扩展名 |
|---|---|
| 图片 | jpg jpeg png gif bmp webp svg ico tiff tif heic |
| 文档 | pdf doc docx xls xlsx ppt pptx txt md csv rtf odt xps |
| 视频 | mp4 mkv avi mov wmv flv webm m4v ts mpeg mpg |
| 程序 | exe msi bat cmd ps1 msc appx |
| 压缩包 | zip rar 7z tar gz bz2 xz iso cab |
未命中的扩展名归入"其他"。分类规则保存在 %APPDATA%\MagicDoor\categories.json,可直接编辑文件(JSON 损坏时自动回退内置规则)。
所有配置位于 %APPDATA%\MagicDoor\:
| 文件 | 说明 |
|---|---|
settings.json |
应用配置(监控列表/门路径/隐藏开关/就绪检测参数/并发数/存量整理开关/日志保留天数等) |
categories.json |
分类规则(可外部编辑或通过设置面板修改) |
pending.json |
待处理队列(建链失败/超时补偿,AttemptCount 超 3 次自动放弃) |
error.log |
未处理异常记录(如有) |
运行日志位于 exe 所在目录 logs\magicdoor_yyyyMMdd.log,按保留天数自动清理。
# 还原 + 构建(零第三方依赖,仅需 .NET 8 SDK)
dotnet build MagicDoor.sln项目包含 220+ 个单元/集成测试(xUnit),覆盖文件就绪检测、分类、链接管理、文件夹监控、断链清理、源文件隐藏、设置面板验证、并发处理等:
dotnet test MagicDoor.sln符号链接相关的集成测试在非管理员/未开开发者模式环境下自动
Skip(跳过原因写入tests\evidence\对应目录),其余测试全部通过。
dotnet publish src\MagicDoor\MagicDoor.csproj `
-c Release -r win-x64 --self-contained true `
-p:PublishSingleFile=true `
-p:IncludeNativeLibrariesForSelfExtract=true `
-p:EnableCompressionInSingleFile=true产物:src\MagicDoor\bin\Release\net8.0-windows\win-x64\publish\MagicDoor.exe(约 71 MB,自包含 .NET 运行时,单文件免安装)。
MagicDoor/
├── MagicDoor.sln # 解决方案
├── magicdoor.txt # 原始需求文档
├── docs/limitations.md # 已知限制文档
├── src/MagicDoor/ # 主程序(.NET 8 WPF)
│ ├── Models/ # AppSettings / CategoryRule / Classification
│ ├── Services/ # 核心服务层
│ │ ├── FolderWatcherService.cs # 文件夹监控(事件→去重→就绪→分发)
│ │ ├── FileReadyDetector.cs # 就绪检测(独占打开+稳定确认)
│ │ ├── LinkManager.cs # 链接管理(分类/序号冲突/断链清理/即时清理)
│ │ ├── FileClassifier.cs # 分类器
│ │ ├── FileHider.cs # 源文件隐藏
│ │ ├── SettingsService.cs # 配置持久化
│ │ ├── LogService.cs # 日志服务
│ │ ├── TrayIconService.cs # 系统托盘
│ │ └── ... # 其余服务(Pending/提权/符号链接等)
│ ├── MainWindow.xaml # 主界面
│ ├── SettingsWindow.xaml # 设置面板
│ └── CategoryEditorWindow.xaml # 分类规则编辑窗口
└── tests/MagicDoor.Tests/ # xUnit 测试
- 技术栈:C# / .NET 8 / WPF(界面)+ WinForms(托盘 NotifyIcon),零第三方依赖,全部系统原生能力。
- 就绪检测:
FileStream(ReadWrite + FileShare.None)独占打开判定"写入完成";下载器以FileShare.Read写文件时会正确判定"仍在写入"。二次长度稳定确认(ReadyStableMs)兼容以FileShare.ReadWrite直写最终名的下载器。 - 临时文件过滤:
.part .crdownload .tmp .download .opdownload .!qb等临时扩展名在 Created 时忽略,等 Renamed 事件处理最终名。 - 门文件夹双保险:监控与建链两层都排除门文件夹路径,防止"链接→事件→再建链接"的无限级联。
- 并发处理:
SemaphoreSlim限流并发(默认 4),StopAsync等待所有 in-flight 任务完成防泄漏。 - 断链判断:用
FileSystemInfo.LinkTarget+ReparsePoint属性判断链接有效性,不用File.Exists(避免误删有效链接)。 - 实时清理三层防护:源文件删除(Deleted 事件前缀匹配)→ 源目录删除(目录前缀匹配递归清理)→ 缓冲区溢出重扫补偿(补发 Created + 清扫断链)。
- 目录遍历安全:手动栈式递归 + 逐目录 try/catch,无权限目录跳过记日志,绝不因单个目录失败中止整个遍历。
详见 docs/limitations.md,要点:
- 不支持 UNC 网络路径监控:
\\开头的路径会被拒绝(提示"不支持网络路径监控")。 - 源文件位于 SMB 共享时:链接创建行为受目标机共享策略限制,建议先复制到本地再整理。
- 创建软链接需管理员或开发者模式:程序提供提权引导;拒绝提权后降级为"仅记录"模式。
- 单文件发布体积较大(约 71 MB,含自包含运行时)。
- 日志随 exe 位置:单文件模式下日志在 exe 所在目录
logs\,移动 exe 请一并迁移历史日志。 - 设置生效时机:就绪检测参数运行中修改将在下次启动生效;分类规则修改后下次启动生效;按扩展名二级分类修改后即时生效;并发处理数修改后下次启动生效。
Q:为什么链接没有自动创建? A:检查①监控是否已启动(状态灯绿色);②源文件是否写入完成(等待就绪超时后进入待处理队列);③是否具备符号链接权限(非管理员会提示提权);④门文件夹是否在监控范围内(会被排除防级联)。
Q:删除源文件后链接没有立即消失? A:正常情况会实时清理。若删除发生在监控范围外的操作(如直接进源目录删除且事件未送达),会在下次启动断链清理时移除。目录级删除已支持前缀匹配递归清理。
Q:重命名源文件后旧链接还在? A:已修复。重命名会自动删除旧链接并创建新链接,无需重启。
Q:批量复制大量文件很慢? A:可在设置中调高"并发处理数"(默认 4,建议不超过 CPU 核心数×2)。
Q:不想整理监控路径里已有的旧文件? A:在设置中取消勾选"添加路径时自动整理已有文件"即可(默认开启,仅对之后新增的文件建链)。
本项目为个人工具项目,代码仅供学习交流使用。
