Files
koring-launcher/electron/handlers/update.ts
T
dream_pep d5004b61d8 feat(更新模块): 提升更新安装安全性并添加统一主进程日志
重构更新验证流程:下载包验证失败时保持为已下载状态并标记校验未通过,而非直接置为错误状态
添加安装校验未通过包时的确认弹窗,支持删除异常安装包
禁用应用退出时自动安装,防止静默安装未校验的包
新增统一主进程日志模块,支持渲染进程通过IPC桥接接入日志
更新已下载但校验失败的UI提示文案
2026-09-04 21:59:10 +08:00

132 lines
4.4 KiB
TypeScript
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.
import electron from 'electron';
import { updateService } from '../updater';
const { ipcMain } = electron;
/**
* 更新 IPC handler。
* - 主进程更新服务初始化后,状态变化广播到所有窗口(update:status
* - 渲染进程通过 update:check / update:download / update:quitAndInstall / update:getState 交互
*/
export function registerUpdateHandlers() {
updateService.init((payload) => {
for (const win of electron.BrowserWindow.getAllWindows()) {
if (!win.isDestroyed()) {
win.webContents.send('update:status', payload);
}
}
});
ipcMain.handle('update:check', async (_event, payload?: { manual?: boolean }) => {
try {
const state = await updateService.check(payload?.manual === true);
return { success: true, data: state, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:download', async () => {
try {
await updateService.download();
return { success: true, data: null, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:pause', () => {
try {
updateService.pause();
return { success: true, data: null, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:resume', async () => {
try {
await updateService.download(); // paused → download() 即继续
return { success: true, data: null, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:cancel', () => {
try {
updateService.cancel();
return { success: true, data: null, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:quitAndInstall', async () => {
try {
// 未核验通过时内部会先弹确认框(继续安装 / 取消并删除安装包)
await updateService.quitAndInstall();
return { success: true, data: null, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('update:getState', () => {
try {
return { success: true, data: updateService.getState(), error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 读取发布说明(release-notes.md 附件,原始 MarkdownGitHub 优先 + 加速源兜底)
ipcMain.handle('update:getReleaseNotes', async (_event, payload?: { tag?: string }) => {
try {
const data = await updateService.getReleaseNotes(payload?.tag);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 更新通道定义列表(woker/runner…,UI 动态渲染)
ipcMain.handle('update:getChannels', () => {
try {
return { success: true, data: updateService.getChannels(), error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 切换更新通道(持久化并立即生效)
ipcMain.handle('update:setChannel', (_event, payload?: { channel?: string }) => {
try {
const state = updateService.setChannel(payload?.channel ?? '');
return { success: true, data: state, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 开发者工具:设置测试版本号(覆盖当前识别版本)
ipcMain.handle('update:setTestVersion', (_event, payload?: { version?: string }) => {
try {
const state = updateService.setTestVersion(payload?.version ?? '');
return { success: true, data: state, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 开发者工具:版本比对(semver)
ipcMain.handle('update:compareVersions', (_event, payload?: { a?: string; b?: string }) => {
try {
const data = updateService.compareVersions(payload?.a ?? '', payload?.b ?? '');
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
}