ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

FlyingMouse Format 0.7.3 稳定性修复深度解读:白屏恢复、LibreOffice 配置回退与保存链路加固

FlyingMouse Format 0.7.3 稳定性修复深度解读:白屏恢复、LibreOffice 配置回退与保存链路加固 桌面应用文档音视频OCR【免费下载链接】flyingmouse-format飞鼠格式 FlyingMouse Format - Windows 免费文件格式转换工具离线可用内置 FFmpeg/LibreOffice/Poppler/Tesseract。图片/文档/表格/PPT/PDF/音视频/WPS 格式互转 OCR 批量转换音频仅支持普通格式。作者牢蜂LaoFeng仅供个人免费使用禁止商业售卖/转卖/套壳项目地址https://gitcode.com/gh_mirrors/fl/flyingmouse-format点击查看免费下载FlyingMouse Format飞鼠格式0.7.3 是一次以「启动、配置保存与转换稳定性」为主线的本地修复版本围绕 0.7.2 提交2750b4087f5b31cd8f516d632262ce88820770d0的隔离副本展开重点解决不同版本/渠道出现的界面白屏、LibreOffice 初始化弹窗卡死、设置跨卷保存EXDEV损坏配置等问题。本文以 版本发布说明 与 修复与验收记录 为骨架结合仓库源码与测试逐一拆解 8 类修复的根因、实现与验收边界帮助读者理解该项目在桌面稳定性、进程治理与文件保存安全上的工程实践。一、版本背景与修复定位0.7.3 是 2026-09-14 记录的候选版本作者牢蜂LaoFeng仅限个人免费使用禁止商业售卖、转卖及套壳。该版本并非新功能版本而是针对此前渠道反馈的三大类稳定性问题做收敛启动期白屏本地导航被代理阻断、渲染进程崩溃或脚本缺失时界面只剩空窗口引擎初始化卡死LibreOffice 在深路径/不可写配置位置初始化失败原生错误弹窗没有 stderr 输出且一直卡住保存与迁移安全设置跨卷保存失败可能损坏已有配置批量保存到不支持硬链接的目标会失败。完整的修复清单与验收证据见 REPAIR-0.7.3.md历史基线为 REPAIR-0.7.2.md本版不回写历史测试结论。二、启动白屏修复直连会话 原生错误提示 重试2.1 问题根因0.7.2 及更早版本中桌面窗口只依赖渲染进程「加载完成」来确认界面可用。当以下任一情况发生时用户会看到空窗口系统/PAC 代理劫持了对127.0.0.1本地服务的请求Chromium 的隐式 loopback 绕过失效主导航加载失败或渲染进程崩溃preload 脚本缺失导致渲染桥不可用。更关键的是加载错误页之前被记为「成功」导致恢复后的旧提示无法触发重新加载已恢复的工作。2.2 实现方式恢复逻辑全部放在主进程的 desktop-recovery.js 中注释明确恢复代码必须存活于主进程因为当渲染文档或 preload 桥不可用时它依然可用且不扩大渲染进程的 IPC origin。核心手段有三点显式直连会话每次start()前调用contents.session.setProxy({ mode: direct })并closeAllConnections()desktop-recovery.js绕过系统代理对 loopback 的干扰且不改变 Windows 系统代理配置就绪监测以渲染进程调用markReady()为准而非did-finish-load启动超时默认 30s、主导航失败、render-process-gone、preload-error、窗口unresponsive事件都会进入失败路径desktop-recovery.js原生重试对话框主进程通过dialog.showMessageBox弹出「重试 / 查看日志 / 关闭」三键提示desktop-recovery.js。用户选择重试时若渲染进程已无响应先forcefullyCrashRenderer()终止导航无法打断不再让出的事件循环再重新start()若界面在弹窗期间已自行恢复则丢弃过期的错误响应不覆盖已恢复的工作。测试 tests/desktop-recovery.test.js 用事件注入方式验证了「先设直连代理 → 关闭连接 → 加载 URL」的顺序、did-finish-load不等于就绪、代理导航失败只弹一次提示且点击 Retry 后可恢复load事件出现两次。三、LibreOffice 配置目录回退与超时进程树终止3.1 问题根因LibreOffice 的 headless 转换需要在UserInstallation下创建大量嵌套文件。即使 Node.js 能接受长路径LibreOffice 的原生组件也未必能使用它。当配置目录过深或不可写时原生程序可能直接弹窗失败——这种弹窗没有 stderr 输出Node 侧无法感知导致进程一直卡住。3.2 短、独占、可写配置目录office-runtime.js 中定义了关键常量与创建逻辑MAX_PROFILE_PATH_LENGTH 160office-runtime.jsWindows 下先计算base office-XXXXXX p的完整长度超过 160 直接放弃该候选候选列表 运行时目录 平台回退目录Windows 为%LOCALAPPDATA%\FlyingMouseFormat\o其他平台为~/.cache/flyingmouse-format/office逐个尝试office-runtime.js每个候选先mkdirSync(base, {recursive, mode:0o700})拒绝符号链接与非常规目录再用mkdtempSync独占创建office-前缀目录防止复用/删除其他任务的配置在p子目录写入.write-probe探针文件验证真实可写office-runtime.js。3.3 错误分类与超时清理office-engine.js 的classifyExecutionError对 stderr 做正则分类其中只匹配明确的「配置创建失败」短语如user installation could not be completed、permission denied避免把 stderr 中偶然出现的 profile 字样误判——office-engine.js 的注释记录了 2026-08-14 一个 docx→pdf 案例roundtrip 失败被误报成「无法创建独立用户配置」实际是转换失败。分类结果映射为多语错误码错误码含义提示文案中文节选OFFICE_ENGINE_MISSING引擎缺失请重新安装完整版本OFFICE_ENGINE_PROFILE_FAILED无法创建独立用户配置检查临时目录权限或安全软件拦截OFFICE_ENGINE_TIMEOUT引擎长时间未响应已尝试结束本次转换请重试OFFICE_ENGINE_INCOMPATIBLE引擎与系统不兼容安装匹配本系统的版本超时清理在 office-process.js 的defaultExecutor中实现。注释明确指出两个平台陷阱office-process.jssoffice.com会派生soffice.bin子进程execFile的内建 timeout 在 Windows 上只杀掉启动器会留下原生错误弹窗和锁定的 profileexecFile不转发detachedPOSIX 进程组需要改用spawn。因此改用spawn(command, args, { windowsHide: true, detached: process.platform ! win32 })office-process.js并通过 owned-tasks.js 登记。超时终止时Windows 走taskkill /PID pid /T /F递归结束整棵进程树office-process.jsPOSIX 走process.kill(-pid, SIGKILL)杀整个进程组office-process.js终止成功与否记录到treeTerminated诊断字段。测试 tests/office-process.test.js 与 tests/office-engine.test.js 均验证了超时后treeTerminated true。关键设计是失败只影响 Office 引擎LibreOffice 不可用时拒绝该引擎的转换非 Office 转换链路保持可用。四、设置跨卷保存EXDEV与降级保留设置保存到另一卷时跨卷rename会失败旧实现在回退到复制的中途失败时可能损坏已有配置。0.7.3 的处理是保存前保留上一次完整配置作为失败时的恢复点EXDEV 回退复制中途失败不会破坏旧配置原有「设置降级不阻断转换」的行为保留——即配置保存失败只是降级提示不会中止转换流程。这与下文第七、九节的保存安全思路一致任何失败路径都不得把用户已有数据置于「丢失中间态」。五、转换任务的快照冻结与选择竞争5.1 问题根因转换期间用户清空或重新选择文件会引入两类竞态转换中的旧请求结果混入新选择慢速识别OCR/扫描结果覆盖新选择的文件。5.2 修复方式界面侧以selectionVersion计数器管理选择代际clearFile()与重新选择时state.selectionVersion 1public/app.js任务入口按快照执行转换开始后clearFile()被if (state.isConverting) return;冻结public/app.js。识别/扫描结果回来时会校验代际过期结果直接拒绝不再覆盖新选择。进度轮询同样带代际校验if (current() snapshot?.id request.id)才更新界面public/app.js确保旧请求的进度不会污染新任务。测试 tests/capability-refresh.test.js 验证了「追加空白 PDF 页时较短的目标快照被拒绝」。六、同名 Word→Markdown 图片目录隔离连续把同名 Word 文档转 Markdown 时旧实现会覆盖上一次的图片目录或继承旧附件。0.7.3 的修复在 office-convert.jsconst mdBasename path.basename(outputNameFor(originalName, md), .md) || document; const assetsDir ${outputPath}.assets;每个转换结果的图片目录按唯一outputPath隔离outputPath.assetsdocx 内嵌的 base64 图片统一通过externalizeMarkdownImages外置写入该目录office-convert.jsMarkdown 内部仍使用下载名.assets/相对引用保存时按附件清单把引用改写为目标目录save-converted-result.js从而保留用户文件名与相对链接同时避免 mammoth 把图片 base64 内嵌成超长单行实测 37 张图单行 263KB 会导致 Typora 拒渲染。七、图片 PDF / ZIP 写流错误处理图片转 PDF、ZIP 打包等链路在写流出错时旧实现可能结束整个进程ZIP 解压损坏时可能一直等待。0.7.3 为这些链路绑定完整流生命周期把失败交回请求方。以 EPUB 写盘为例ebook.js 的writeEpubArchive展示了典型模式用fs.createWriteStream(outputPath, { flags: wx })独占创建输出文件目标流error时先解绑再 drainzip.outputStream.unpipe(output); zip.outputStream.resume();——否则 yazl 的私有压缩器会因背压卡死后续 lazy 回调永远不执行ebook.js流在完成前close视为EPUB_WRITE_FAILED只允许删除自己独占创建的文件通过identity的dev/ino校验绝不删除替换者。八、PDF 分组拆分回退与加密 PDF 拒绝针对 qpdf 缺失时分组拆分忽略每组页数的问题0.7.3 让回退路径遵循相同的分组规则加密 PDF 合并、无法解密的拆分回退则明确拒绝不生成空正文的伪成功结果。测试 tests/conversion-integrity.test.js 验证了「加密 PDF 合并与回退拆分在发布空密文页前拒绝」。九、启动清理精确化启动时的临时目录清理可能误删超过一天但仍存活实例的结果或同名前缀的备份。修复后的 desktop-shutdown.js 采用身份捕获 断言机制captureRuntimeIdentity只接受形如flyingmouse-format-runtime-pid的精确目录拒绝符号链接与非安全 PIDdesktop-shutdown.js清理前assertRuntimeIdentity比对dev/ino与realpath目录被替换如被软链指向外部时拒绝清理desktop-shutdown.js只清理确已退出的进程对应的目录。同时 Office 不再自动删除其他代际的缓存保留旧缓存有磁盘占用代价见验证边界跨代缓存的管理交给 store-engine-cache.js 的独立事务。十、非 NTFS 目标保存的硬链接回退批量保存到 FAT/exFAT 等不支持硬链接的目标会失败。0.7.3 在 save-download.js 的publishDownloadedFile中实现硬链接优先、排他复制回退不覆盖模式下先fs.promises.link(stagedPath, destination)——硬链接以 EEXIST 原子失败天然防覆盖竞争捕获ENOTSUP / EOPNOTSUPP / ENOSYS / EXDEV / EPERM / EISDIRlibuv 会把 WindowsERROR_INVALID_FUNCTION翻译成 EISDIR后改用copyFile(..., COPYFILE_EXCL)排他复制save-download.js复制完成之后才报告成功仍拒绝覆盖同名结果。下载本身始终先写目标同目录的随机.partial临时文件同卷 rename 才是原子的见 save-download.js收全、关流、字节数校验通过后才发布任何失败只清理本次创建的.partial绝不触碰用户已存在的目标文件。诊断导出同样使用独占临时文件发布写入失败时保留旧文件。十一、本地转换接口来源收紧转换 HTTP API 此前允许其他 localhost 端口的来源。0.7.3 在 server.js 收紧为function isLocalWebOrigin(value, localPort) { if (!value) return false; try { const url new URL(value); return !url.username !url.password url.origin http://127.0.0.1:${localPort}; } catch { return false; } }只接受精确的http://127.0.0.1:当前监听端口origin且不允许 URL 携带用户名/密码Origin与Referer两个头都校验任一不合法即返回 403server.js保留无浏览器 Origin 的 CLI调用路径CLI 请求不带 Origin 头不受影响收紧安全策略的同时保留原有鼠鼠界面、主题与语言偏好不因安全修复牺牲既有功能。十二、打包链路修复APPX PowerShell 5.1 与 macOS CI 进程组12.1 APPX 打包损坏 Node 内联参数APPX 默认使用 PowerShell 5.1 打包内联的 Node 参数会被错误解析。修复方式把目录校验逻辑写入本次独占的脚本文件后再执行实际完成封包与校验脚本路径由本次任务独占避免与其他实例竞争。12.2 macOS CI 的进程组问题首轮远程 macOS CI 暴露Office 超时清理未建立独立进程组——execFile不转发detached。修复后改为实际创建进程组的进程启动方式见第三节的spawndetached同时保持输出上限MAX_BUFFER1MB见 office-process.jsWindows 精确进程树清理taskkill /T深 TEMP 冒烟测试改为按平台检查是否使用过回退目录。注意验收口径首轮 Windows 门禁通过不能记为跨平台成功两个 macOS 架构的失败与修复后的 CI 必须按各自提交分别核对。十三、验证与发布状态0.7.3 的验收证据记录于 REPAIR-0.7.3.md测试计数前置结构测试 104/104主测试 686 通过、0 失败、12 跳过合计 790 通过、0 失败最终 EXE 的 HTTP 转换矩阵62 通过、0 失败、1 个引擎缺失场景不适用生产依赖审计0 个已知漏洞包内容核对64 项关键文件/manifest 内容与最终源码核对通过真实环境复现真实 Electron 验证代理、主导航阻断、脚本缺失与渲染崩溃恢复实际 Windows 原生对话框点击 Retry 后恢复真实 UI 验证异步选择竞争、转换冻结、两份 TXT→Markdown 原文与两种双页 PDF 合并真实 LibreOffice 深 TEMP 配置回退产出 PDF初始化超时后无本次子进程残留Store Worker 缓存在接近日常用户目录长度的隔离根完成冷缓存16.656 秒、51 文件校验与真实转换、暖缓存0.635 秒及准备期间的非 Office 转换——注意这是隔离根验证不是 Store 容器安装测试。发布口径Windows 10/11 x64 候选安装器NSIS与 APPX 已构建并记录校验本机程序已更新至 0.7.3便携目录部署非 NSIS 安装流程EXE/ASAR 与已测最终构建完全一致未上传商店、未公开发布公开发布与 Microsoft Store 上架状态以渠道实际显示为准README 的版本文件名是待发布候选名称。十四、验证边界与注意事项极深的自定义 LibreOffice 引擎资源路径仍可能失败长根缓存验证返回退出码3221226505短根成功不能仅凭该错误码判定具体原生原因也不能把配置目录回退描述为「解决所有引擎资源长路径」。失败仍拒绝该 Office 引擎非 Office 保持可用未复测范围原反馈机器、正常 Store 容器、实体 FAT/exFAT、Win7 及 macOS 尚未完成本版复测用户截图来自不同版本/渠道无法据此保证任意安全软件拦截、损坏系统或磁盘故障均可自动修复断电语义非 NTFS 保存通过真实文件复制与不支持硬链接的错误注入验证但复制完成后才报成功断电时不保证新文件原子可见缓存改名支持中断后恢复但不是物理断电或磁盘损坏的事务保证保留旧缓存有磁盘占用代价未知锁、磁盘损坏和断电事务不作额外保证跳过项缺少的 OFD、Gutenberg、特定 OCR/PDF 样本列为跳过不计通过普通极大输入仍受既有引擎和内存约束未把占位上限宣传为无限能力平台声明Win7/macOS 未构建或做设备验收保留原鼠鼠 UI、主题、中英切换、非商用署名与现有格式边界音频仅支持普通格式。结语0.7.3 的工程价值不在于新功能而在于把三类高危稳定性问题系统性地收口界面层通过主进程直连会话与原生重试把「空窗口」变成可恢复的明确故障引擎层通过短独占配置目录与进程树终止把「无声卡死」变成可诊断、可清理的错误保存层通过.partial暂存、硬链接/排他复制回退与身份校验把「失败即损坏」变成「失败即保全」。结合 release-notes-073.md 与 REPAIR-0.7.3.md 中诚实的验收边界声明这套「修复—复现—边界—发布」的记录方式本身就是值得参考的桌面应用工程实践。赞分享桌面应用文档音视频OCR【免费下载链接】flyingmouse-format飞鼠格式 FlyingMouse Format - Windows 免费文件格式转换工具离线可用内置 FFmpeg/LibreOffice/Poppler/Tesseract。图片/文档/表格/PPT/PDF/音视频/WPS 格式互转 OCR 批量转换音频仅支持普通格式。作者牢蜂LaoFeng仅供个人免费使用禁止商业售卖/转卖/套壳项目地址https://gitcode.com/gh_mirrors/fl/flyingmouse-format点击查看免费下载相关推荐The Node.js Foundation benefits allThe Node.js Foundation benefits all 导读 本文是一篇发布于 2015 年 5 月的社区历史博文由时任 Joyent CEO桌面应用文档音视频OCRClickHouse v25.3.3.42 LTS 补丁版本解读BFloat16 类型转换修复、副本恢复加固与复制链路稳定性提升ClickHouse v25.3.3.42 LTS 补丁版本解读BFloat16 类型转换修复、副本恢复加固与复制链路稳定性提升 本篇文章围绕 ClickHo数据库OLAP列式数据库大数据实时分析数据分析OfficeCLI完全指南快速用命令自动化Word、Excel、PPT免装OfficeOfficeCLI完全指南快速用命令自动化Word、Excel、PPT免装Office 每月的客户数据要手工粘进Excel、写公式、再做一份汇报PPT一个零信任网络后端认证鉴权上一篇FinalBurn Neo免费开源街机模拟器完整指南下一篇GoldHEN Cheats Manager让PS4游戏修改变得如此简单的终极指南 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进