- 新增check_url_protocol_status命令检测注册状态 - 新增unregister_url_protocol命令取消注册 - 改进register_url_protocol命令增加验证逻辑 - 前端增加状态检测、自动重试和操作日志功能 - 更新多语言翻译支持新功能
9.5 KiB
URL 协议注册健壮性增强计划
目标
为 SecScore 的 URL 协议注册功能实现完整的健壮性增强,包括:状态检测、注册验证、自动重试(最多7次)、按钮状态自动切换、取消注册、以及全流程日志记录。
涉及文件
| 文件 | 操作 | 说明 |
|---|---|---|
src-tauri/src/commands/app.rs |
修改 | 新增 check_url_protocol_status、unregister_url_protocol 命令;增强 register_url_protocol |
src-tauri/src/lib.rs |
修改 | 注册新命令到 invoke_handler |
src/preload/types.ts |
修改 | 新增 API 类型定义 |
src/components/Settings.tsx |
修改 | 重写 URL 协议 UI,加入状态显示、重试逻辑、按钮切换 |
src/i18n/locales/*.json (10个) |
修改 | 新增 i18n 翻译键 |
步骤 1:Rust 后端 - 新增 UrlProtocolStatus 结构体和 check_url_protocol_status 命令
文件: src-tauri/src/commands/app.rs
1.1 新增结构体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UrlProtocolStatus {
pub registered: bool,
pub protocol: String,
pub platform: String,
pub details: String,
}
1.2 实现 check_url_protocol_status 命令
按平台实现 URL 协议状态检测:
-
Windows: 查询注册表
HKCU\Software\Classes\secscore是否存在,检查URL Protocol值和shell\open\command中的路径是否指向当前 exe -
macOS:
- 先尝试通过
lsregister -dump查询secscore://scheme 的注册状态 - 检查
~/Library/LaunchAgents/com.secscore.url-handler.plist是否存在(非 .app bundle 场景)
- 先尝试通过
-
Linux:
- 检查
~/.local/share/applications/secscore.desktop是否存在且包含x-scheme-handler/secscore - 通过
xdg-settings get default-url-scheme-handler secscore验证是否为默认处理器
- 检查
返回 UrlProtocolStatus 结构体,包含注册状态、当前平台、检测详情。
步骤 2:Rust 后端 - 新增 unregister_url_protocol 命令
文件: src-tauri/src/commands/app.rs
按平台实现取消注册:
-
Windows: 删除注册表
HKCU\Software\Classes\secscore键 (reg delete "HKCU\Software\Classes\secscore" /f) -
macOS:
- 如果存在 .app bundle,通过
lsregister -u取消注册 - 删除
~/Library/LaunchAgents/com.secscore.url-handler.plist
- 如果存在 .app bundle,通过
-
Linux:
- 删除
~/.local/share/applications/secscore.desktop - 运行
update-desktop-database
- 删除
步骤 3:Rust 后端 - 增强 register_url_protocol 命令
文件: src-tauri/src/commands/app.rs
改造现有 register_url_protocol:
- 执行注册操作后,不再盲目返回
registered: Some(true) - 注册完成后,自动调用状态检测逻辑验证注册是否成功
- 返回实际检测到的注册状态(
registered字段反映真实结果) - 在每个关键步骤添加
eprintln!日志输出(Rust 端日志)
步骤 4:Rust 后端 - 注册新命令
文件: src-tauri/src/lib.rs
在 invoke_handler 中添加:
-
check_url_protocol_status -
unregister_url_protocol
步骤 5:前端 API 类型定义
文件: src/preload/types.ts
新增 API 方法:
checkUrlProtocolStatus: (): Promise<{
success: boolean
data?: {
registered: boolean
protocol: string
platform: string
details: string
}
message?: string
}> => invoke("check_url_protocol_status"),
unregisterUrlProtocol: (): Promise<{
success: boolean
data?: { registered: boolean }
message?: string
}> => invoke("unregister_url_protocol"),
步骤 6:前端 Settings.tsx - 重写 URL 协议卡片 UI
文件: src/components/Settings.tsx
6.1 新增状态变量
const [urlStatus, setUrlStatus] = useState<{ registered: boolean; details: string } | null>(null)
const [urlStatusLoading, setUrlStatusLoading] = useState(false)
const [urlOperationLogs, setUrlOperationLogs] = useState<string[]>([])
6.2 状态检测逻辑
-
组件加载 URL tab 时自动执行一次
checkUrlProtocolStatus -
在 UI 中显示当前注册状态(Tag: 已注册/未注册 + 详情文本)
6.3 注册流程(含自动重试)
handleRegister():
1. 记录日志:"开始注册 URL 协议..."
2. 调用 registerUrlProtocol()
3. 记录日志:"注册命令已执行,开始验证..."
4. 调用 checkUrlProtocolStatus() 验证
5. IF 注册成功:
- 记录日志:"注册验证成功"
- 更新状态显示
- 完成
6. ELSE (注册失败):
- FOR retry = 1 TO 7:
- 记录日志:"注册失败,第 {retry}/7 次重试..."
- 延迟 retry * 1000 ms (递增延迟: 1s, 2s, 3s, ..., 7s)
- 调用 registerUrlProtocol()
- 调用 checkUrlProtocolStatus() 验证
- IF 成功:
- 记录日志:"第 {retry} 次重试成功"
- 更新状态,退出循环
- ELSE:
- 记录日志:"第 {retry} 次重试失败"
- IF 7次全部失败:
- 记录日志:"已达最大重试次数(7次),注册失败"
- 显示错误消息
6.4 按钮状态自动切换
根据 urlStatus.registered 动态渲染:
| 状态 | 按钮文本 | 按钮类型 | 点击行为 |
|---|---|---|---|
| 未注册 | "注册 URL 协议" | primary | 执行注册(含重试) |
| 已注册 | "重新注册" | default | 执行注册(覆盖注册+验证) |
| 已注册 | "取消注册" | danger | 执行 unregisterUrlProtocol + 验证 |
6.5 操作日志展示
在 URL 协议卡片底部增加一个可折叠的 <Collapse> 或简洁的 <Typography.Paragraph> 区域,展示最近的操作日志(最多保留最新 20 条),使用 fontSize: 12px, fontFamily: monospace 样式。
步骤 7:i18n 翻译
文件: src/i18n/locales/ 下所有 10 个语言文件
在 settings.url 下新增以下键:
| 键 | zh-CN | en-US |
|---|---|---|
checkStatus |
"检测状态" | "Check Status" |
reRegister |
"重新注册" | "Re-register" |
unregister |
"取消注册" | "Unregister" |
unregistered |
"URL 协议已取消注册" | "URL protocol unregistered" |
unregisterFailed |
"取消注册失败" | "Failed to unregister" |
statusRegistered |
"已注册" | "Registered" |
statusNotRegistered |
"未注册" | "Not Registered" |
statusCheckFailed |
"状态检测失败" | "Status check failed" |
retrying |
"重试中 ({current}/{max})" | "Retrying ({current}/{max})" |
retryFailed |
"已达最大重试次数,注册失败" | "Max retries reached, registration failed" |
retrySuccess |
"第 {n} 次重试成功" | "Retry #{n} succeeded" |
operationLog |
"操作日志" | "Operation Log" |
logRegisterStart |
"开始注册 URL 协议..." | "Starting URL protocol registration..." |
logRegisterVerify |
"注册命令已执行,正在验证..." | "Registration command executed, verifying..." |
logRegisterSuccess |
"注册验证成功" | "Registration verified successfully" |
logRegisterFailed |
"注册验证失败" | "Registration verification failed" |
logUnregisterStart |
"正在取消注册..." | "Unregistering..." |
logUnregisterSuccess |
"取消注册成功" | "Unregistered successfully" |
logUnregisterFailed |
"取消注册失败" | "Unregister failed" |
logMaxRetries |
"已达最大重试次数 (7次)" | "Max retries (7) reached" |
其余 9 个语言文件同步翻译。
步骤 8:运行测试与格式化
- 执行
pnpm run typecheck(如有)检查前端类型 - 执行
cargo check检查 Rust 编译 - 执行格式化命令
- 运行测试套件
实现顺序
- ✅ 步骤 1:Rust -
check_url_protocol_status - ✅ 步骤 2:Rust -
unregister_url_protocol - ✅ 步骤 3:Rust - 增强
register_url_protocol - ✅ 步骤 4:Rust - 注册新命令到 lib.rs
- ✅ 步骤 5:前端 API 类型
- ✅ 步骤 6:前端 Settings.tsx UI
- ✅ 步骤 7:i18n 翻译
- ✅ 步骤 8:测试与格式化