Files
omni-notify/docs/development.md
2026-05-20 12:53:24 +08:00

190 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Omni-Notify 开发者文档
本文档面向需要构建、修改、审查或发布 Omni-Notify 的开发者。最终用户安装和使用说明请见 [README.md](../README.md)。
## 技术栈
- .NET 8
- WPF
- Windows Forms `NotifyIcon`
- Built-in `HttpListener`
- JSON 本地持久化
项目不依赖第三方 NuGet 包。
## 项目结构
| 文件 | 责任 |
| --- | --- |
| `App.xaml.cs` | 应用生命周期、单实例互斥、托盘入口、本地 HTTP 服务启动 |
| `MainWindow.xaml` | 主控制面板 UI |
| `MainWindow.xaml.cs` | 频道管理、历史筛选、全局设置保存 |
| `Models.cs` | 应用状态、频道、弹窗样式、历史记录、输入消息模型 |
| `Services.cs` | 状态持久化、消息路由、限流熔断、本地 HTTP 接收服务 |
| `PopupCoordinator.cs` | 弹窗队列、堆叠、替换和位置计算 |
| `PopupWindow.xaml` | 单个弹窗窗口 UI |
| `PopupWindow.xaml.cs` | 弹窗动画、生命周期和正文溢出处理 |
| `app.manifest` | Windows 应用清单,声明普通用户权限运行 |
| `scripts/package-release.ps1` | 标准发布脚本 |
## 本地构建
```powershell
dotnet build .\OmniNotify.csproj -c Release
```
目标框架:
```xml
net8.0-windows
```
应用类型为 WPF 桌面应用,输出为 `WinExe`
## 本地运行
```powershell
dotnet run --project .\OmniNotify.csproj
```
默认监听:
```text
http://127.0.0.1:19845/
```
通知接口:
```text
POST http://127.0.0.1:19845/notify
```
请求体:
```json
{
"channel": "default",
"title": "Build finished",
"body": "The nightly job completed successfully."
}
```
## 状态持久化
状态文件路径:
```text
%LOCALAPPDATA%\OmniNotify\state.json
```
保存内容包括:
- 全局设置
- 频道列表和频道样式
- 历史记录
`AppStore.Save` 会在写入前清理超出保留天数和数量限制的历史记录。
## 消息处理流程
1. `LocalHttpServer` 接收本地 HTTP 请求。
2. 请求体反序列化为 `IncomingMessage`
3. `NotificationRouter.Receive` 进入 UI Dispatcher。
4. 检查熔断状态和每秒消息上限。
5.`channel` 严格匹配频道。
6. 根据免打扰状态决定是否弹窗。
7. 写入历史记录。
8. `PopupCoordinator` 按频道样式显示弹窗。
未知频道不会弹窗,会记录为 `IllegalChannel`
## 发布包
生成 v0.2.0 Windows x64 发布包:
```powershell
.\scripts\package-release.ps1 -Version 0.2.0
```
默认产物:
```text
artifacts\omni-notify-v0.2.0-win-x64.zip
```
脚本参数:
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `Configuration` | `Release` | 构建配置 |
| `Version` | `0.2.0` | 应用版本和产物版本 |
| `RuntimeIdentifier` | `win-x64` | 目标运行时标识 |
## 发布策略
当前发布策略刻意保持透明、标准和低风险:
- `SelfContained=false`
- `PublishSingleFile=false`
- `PublishTrimmed=false`
- `PublishReadyToRun=false`
- `--self-contained false`
- 不使用混淆器
- 不使用 UPX
- 不使用自解压启动器
- 不请求管理员权限
发布脚本会检查产物目录中是否出现以下 .NET 运行时文件:
- `coreclr.dll`
- `clrjit.dll`
- `hostfxr.dll`
- `hostpolicy.dll`
如果出现这些文件,脚本会失败,避免误发布自包含运行时包。
## 安全敏感行为约束
v0.2.0 已删除开机自启功能。代码中不应重新引入以下行为,除非经过明确产品决策:
- 写入 `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
- 创建计划任务实现自启动
- 后台下载或执行外部程序
- 全局键盘/鼠标钩子
- 注入、提权、隐藏进程或绕过安全产品
应用保留的本地监听服务仅绑定 `127.0.0.1`,不应改为 `0.0.0.0` 或局域网地址,除非同时补充认证和明确的安全设计。
## 版本与 Git
发布新版本时:
1. 更新 `OmniNotify.csproj` 中的 `Version``FileVersion``AssemblyVersion`
2. 更新 `app.manifest` 中的 `assemblyIdentity version`
3. 更新文档中的示例版本号。
4. 运行发布脚本生成 zip。
5. 验证发布目录不包含 .NET 运行时文件。
6. 提交代码。
7. 创建 tag例如 `v0.2.0`
8. 推送分支和 tag。
建议 tag 命名:
```text
vMAJOR.MINOR.PATCH
```
建议发布资产命名:
```text
omni-notify-vMAJOR.MINOR.PATCH-win-x64.zip
```
## v0.2.0 发布摘要
- 删除开机自启功能及相关注册表写入逻辑。
- 新增标准应用清单,声明普通用户权限运行。
- 新增 framework-dependent 发布脚本。
- 发布包改为 `omni-notify-v0.2.0-win-x64.zip`
- README 改为用户文档,开发信息迁入本文档。