灵伴桌面宠物 — 技术架构文档
1. 架构总览
┌──────────────────────────────────────────────────────────┐
│ Electron 主进程 │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ main.js │ │ config-store │ │ task-scheduler │ │
│ │ 窗口管理 │ │ 配置持久化 │ │ 任务调度 │ │
│ │ IPC 通信 │ │ 数据校验 │ │ PS 脚本执行 │ │
│ │ 系统托盘 │ │ 原子写入 │ │ 日志记录 │ │
│ └──────┬───────┘ └──────┬───────┘ └───────┬────────┘ │
│ │ │ │ │
│ └─────────────────┼───────────────────┘ │
│ │ IPC (contextBridge) │
└───────────────────────────┼───────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
┌───────▼──────┐ ┌───────▼──────┐ │
│ preload.js │ │ preload.js │ │
│ (API 桥接) │ │ (API 桥接) │ │
└───────┬──────┘ └───────┬──────┘ │
│ │ │
┌───────▼──────┐ ┌───────▼──────┐ │
│ 宠物窗口 │ │ 控制中心窗口 │ │
│ pet.html │ │ manager.html │ │
│ pet.css │ │ manager.css │ │
│ pet.js │ │ manager.js │ │
└──────────────┘ └──────────────┘ │
│
┌───────────▼──────────┐
│ 数据存储层 │
│ config.json │
│ (任务/设置/宠物图片) │
│ task-runs.log │
└──────────────────────┘
2. 进程模型
2.1 主进程 (src/main.js)
职责:
- 应用生命周期管理
- 窗口创建与管理(宠物窗口 + 控制中心窗口)
- 系统托盘创建与交互
- IPC 通信处理(15 个通道)
- 单实例锁控制
关键设计:
- 宠物窗口:
transparent: true, frame: false, alwaysOnTop: true - 控制中心窗口:1060x760,常规窗口
- IPC 安全:
isAllowedSender()校验file://协议
2.2 预加载脚本 (src/preload.js)
职责:通过 contextBridge.exposeInMainWorld('lingPet', api) 安全暴露 API
暴露的方法分类:
| 类别 | 方法 |
|—|—|
| 状态 | getState(), onStateChanged(), onTaskEvent() |
| 设置 | setSetting(), setScale() |
| 宠物交互 | beginPetDrag(), movePetDrag(), endPetDrag(), togglePet(), showContextMenu() |
| 图片 | choosePetImage(), resetPetImage() |
| 任务 | saveTask(), toggleTask(), deleteTask(), runTask(), resetTasks() |
| 其他 | openManager(), adoptLegacyTasks(), openDataFolder(), openLog(), reportDiagnostic() |
2.3 渲染进程
| 进程 | 文件 | 功能 |
|---|---|---|
| 宠物窗口 | pet.html/css/js |
动画渲染、拖拽交互、粒子效果、缩放 |
| 控制中心 | manager.html/css/js |
任务管理 UI、设置面板、宠物预览 |
3. 核心模块设计
3.1 配置存储 (config-store.js)
数据结构:
{
settings: {
autoStart: boolean, // 开机自启
alwaysOnTop: boolean, // 总在最前
animation: boolean, // 动态效果
visible: boolean, // 宠物可见
scale: number, // 缩放比例 (0.5~1.75)
position: {x, y} | null, // 宠物位置
customImage: string|null // 自定义图片路径
},
tasks: [
{
id: string,
name: string,
time: "HH:mm",
enabled: boolean,
description: string,
script: string
}
]
}
特性:
- 存储路径:
%APPDATA%/<userData>/config.json - 原子写入:先写
.tmp再rename - 容错:损坏时备份为
.broken-{timestamp}并恢复默认 - 校验:名称非空、时间 HH:mm、脚本非空
3.2 任务调度器 (task-scheduler.js)
调度流程:
setInterval(5s) → tick()
→ 遍历所有启用任务
→ 比对当前时间 HH:mm 与任务时间
→ 检查 lastRunDate !== today
→ 写入 .ps1 文件 (UTF-8 BOM)
→ powershell.exe -File xxx.ps1
→ 记录 stdout/stderr (最近16KB)
→ 写入 task-runs.log
→ 发送 started/finished/error 事件
防重复机制:lastRunDate Map,同一天不重复触发
3.3 内置任务模板
3 个内置任务均针对 Wallpaper Engine:
| 任务 | 时间 | 脚本功能 |
|---|---|---|
| 早起 | 08:00 | 启动 Wallpaper Engine |
| 锻炼 | 20:00 | 切换 Wallpaper Engine 壁纸 |
| 早睡+关机 | 23:00 | 停止 Wallpaper Engine,15分钟后关机 |
4. 数据流
用户操作 → 渲染进程 → IPC (preload) → 主进程
├── ConfigStore (持久化)
├── TaskScheduler (调度)
└── 窗口操作 (移动/缩放/显隐)
主进程状态变更 → IPC → 渲染进程 (onStateChanged/onTaskEvent)
5. 构建与打包
| 命令 | 功能 |
|---|---|
npm start |
开发模式启动 |
npm run pack |
打包为目录 |
npm run dist |
生成 NSIS 安装包 |
npm test |
运行集成测试 |
打包配置 (electron-builder):
- 目标:NSIS (Windows)
- 架构:x64
- 输出目录:
dist/ - 包含资源:
assets/**,build/icon.ico - 自定义 NSIS 脚本:
build/installer.nsh(卸载时清理注册表)
6. 安全设计
- IPC 安全:主进程校验所有 IPC 请求来源,仅允许已知窗口的
file://协议 - CSP 策略:宠物窗口
default-src 'self',图片file:+data: - contextBridge:渲染进程无法直接访问 Node.js API
- 单实例锁:
app.requestSingleInstanceLock()防止多开