← 跨平台应用开发 · 第 6 篇

Electron 桌面工具怎样隔离文件和界面权限

为访谈片段整理器划分Electron主进程、preload和界面职责,用文件授权ID、受限IPC和任务状态管理转录。

学完这一篇,你能做到

实现文件选择与受限IPC,验证非法动作、未授权文件、取消任务和转录失败不会扩大界面权限。

访谈片段整理器允许用户选择音频,查看转录任务,再校对片段。文件访问和转录执行拥有比界面更多的权限。把 Node.js 接口直接交给页面,会让界面中的不可信文本或脚本有机会影响本地操作。

案例只使用合成音频或用户明确选择的教学文件。转录引擎先用假任务返回结果;接入真实本地或云端引擎时再核对格式、资源和数据流。本课不声称某段录音已被正确转录。

三个执行边界怎样连接

Electron 主进程运行在 Node.js 环境,管理窗口和本地能力;renderer 展示页面;preload 在两者之间提供有限桥梁。每个窗口有自己的 renderer,页面不应该直接取得任意文件、shell 或全部 IPC 接口。

启用 context isolation、renderer sandbox,并关闭不需要的 Node integration。安全配置是基础,消息仍必须检查发送者、窗口来源、动作与参数。一个允许任意频道和参数的“通用调用”会绕开窄接口设计,即使 context isolation 已开启也有风险。

preload 只暴露选择音频、开始任务、取消任务和读取状态等明确能力。返回值是可序列化数据,不把内部对象或文件句柄随意传给界面。日志同样不能包含用户完整路径、正文或秘密。

文件授权与任务记录

用户点击选择按钮后,由主进程打开系统文件选择器。主进程记录选中路径并返回临时文件 ID、显示名称和大小。renderer 后续只提交文件 ID,不能通过自己拼出的路径扩大文件访问范围。

授权表关联文件 ID、允许使用的窗口与有效期限。窗口关闭或文件被移除时使授权失效。开始任务前再次检查文件存在、类型与大小,文件选择后的检查结果可能已经过期;错误必须返回可理解状态,而不是让任务永远停在排队中。

任务记录包含任务 ID、文件 ID、阶段、进度、错误码与取消状态。排队、运行、成功、失败、取消是不同结果。转录输出保留片段时间和文本供校对;模型置信度或输出形式不能替代人工确认,尤其是姓名、数字和专业术语。

建立 Electron 最小工程

按官方入门工程配置 Electron,并锁定依赖版本。创建主入口、preload、renderer 的 HTML 与脚本。主进程在应用就绪后创建窗口,加载自己的本地界面,同时设置安全 webPreferences 与限制内容安全策略。本文工程步骤供读者执行,不是已实测应用的记录。

先实现文件选择,确认取消不会产生任务。再通过限定的 ipcMain.handle 与 preload 桥梁连接假转录服务,给它可控延迟与错误。renderer 显示文件名、开始按钮、进度和取消入口;权限检查始终在主进程完成。

之后接入真实引擎适配器,执行耗时工作时保持主进程可响应。适配器定义输入格式、输出片段和退出条件;不要将任意模型文本拼成命令执行。若需要外部进程,参数由受控配置生成,文件仍来自已授权表,执行环境另外审核。

离线校验窄消息契约

下面 Python 代码接受唯一动作和预先批准的文件 ID,也拒绝多余字段。它是消息结构模型,没有 Electron、文件选择器、IPC 发送者或实际文件系统。

approved = {"F-1"}
def permit(message):
    return (isinstance(message, dict) and set(message) == {"action", "file_id"}
            and message["action"] == "transcribe" and message["file_id"] in approved)
assert permit({"action": "transcribe", "file_id": "F-1"})
assert not permit({"action": "delete", "file_id": "F-1"})
assert not permit({"action": "transcribe", "file_id": "/private/file"})
print(permit({"action": "transcribe", "file_id": "F-1"}))

实际输出 True。删除动作与直接传入路径都被拒绝。真实实现还需要检查字段类型与长度、发送窗口和 frame 来源,并处理未知 ID。结构合法不表示调用者有权访问,不能仅复制这个函数作为完整授权方案。

按动作分别定义 schema 比一个万能 JSON 接口更易审查。取消请求验证任务归属;查询状态只返回当前窗口可见任务。主进程收到异常参数应返回受控错误,避免让错误信息泄露内部路径。

转录任务的取消与恢复

取消先记录意图,再通知执行器停止,最终由执行器确认结束。用户看到的取消完成应对应资源已经释放或任务已无法提交结果。较晚返回的成功不能重新显示为完成任务,应按任务状态拒绝提交。

输出先进入自己创建的临时位置,完整校验后再提交片段索引。失败保留已确认的旧结果,不把部分写入当成功。需要恢复的任务持久化最小信息;重启后判断是可重新执行还是已经失去文件授权,让用户重新选择。

临时文件清理只处理应用创建并追踪的内容。不要从 renderer 传来的目录推导递归删除目标。大小限制、并发上限与队列长度要按测试资源设置,不用未经测量的速度承诺决定体验。

本地与云端数据选择

本地引擎需要安装与资源,云端引擎涉及上传和服务凭证。界面要在发送前明确哪种路径会使用文件,用户取消上传时停止后续发送。秘密保留在合适的受限环境,renderer 不获得服务密钥。

转录质量受到语言、噪音与音频条件影响。Whisper 论文提供模型背景,不能证明任意访谈准确。整理器应让用户回听片段、编辑文本并标记待复核,导出保留来源与修改状态,避免把自动生成内容当最终记录。

片段编辑与任务输出也要分离。用户修正后保存编辑版本,重新转录生成新候选,不直接覆盖已校对文本。导出记录明确选择候选或校对版,时间范围要落在实际音频长度内,重叠或缺失片段留给人工检查。

界面显示任务进度应说明它是执行器报告的阶段,未知进度使用不定进度提示。任务结束时检查输出结构、时间顺序和文本字段,拒绝异常巨大结果。模型可能遗漏片段,格式校验成功只说明结构符合契约,不能自动把整份转录标记为准确。测试空音频与无识别文本时,应显示可解释结果。

练习:从权限测试到安装测试

用假引擎测试未授权 ID、额外字段、未知动作、窗口关闭、文件消失和取消后的晚到结果。每个路径应返回确定错误或结束状态,界面仍能操作,主进程不接受任意文件路径。

再在目标桌面系统打包并安装测试,检查文件选择、资源加载与权限。更新需要可信来源和签名策略,安全依赖也需持续维护。记录真实测过的系统与产物;IPC 模型断言通过只验证该消息契约,不保证完整桌面应用安全或转录质量。

资料来源与延伸阅读

资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。