Files
nl-um-vue-ts/electron/preload.ts
2026-08-24 15:24:00 +08:00

80 lines
4.2 KiB
TypeScript
Raw Permalink 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.
/**
* Electron 预加载脚本
*
* 作用:在上下文隔离(contextIsolation)环境下,通过 contextBridge 向渲染进程暴露
* 受控的桌面能力 APIwindow.electronAPI。渲染进程无法直接访问 Node/Electron
* 只能调用这里明确列出的方法,保证安全边界。
*
* 渲染层对应的类型声明见 src/types/electron.d.ts两边需保持同步
*/
import { contextBridge, ipcRenderer } from 'electron'
import type { IpcRendererEvent } from 'electron'
/** 订阅主进程事件的通用封装:返回取消订阅函数,方便组件卸载时清理 */
function subscribe<T>(channel: string, callback: (payload: T) => void): () => void {
const listener = (_event: IpcRendererEvent, payload: T) => callback(payload)
ipcRenderer.on(channel, listener)
return () => {
ipcRenderer.removeListener(channel, listener)
}
}
const electronAPI = {
/** 当前运行平台win32/darwin/linux渲染层可用于平台差异化处理 */
platform: process.platform,
// ---------- 应用信息 ----------
/** 获取应用版本号package.json version设置弹窗展示用 */
getVersion: (): Promise<string> => ipcRenderer.invoke('app:get-version'),
// ---------- 窗口 ----------
/** 显示并聚焦主窗口 */
focusWindow: (): Promise<void> => ipcRenderer.invoke('win:focus'),
/** 设置任务栏未读角标count=0 清除。角标图片由渲染层 canvas 生成(主进程无 DOM */
setBadge: (count: number, dataURL?: string): Promise<void> =>
ipcRenderer.invoke('win:set-badge', count, dataURL || ''),
/** 请求任务栏闪烁提醒(仅窗口未聚焦时生效,聚焦后自动停止) */
flashFrame: (): Promise<void> => ipcRenderer.invoke('win:flash'),
// ---------- 系统通知 ----------
/** 发送系统级通知(点击通知会显示并聚焦主窗口) */
notify: (options: { title: string; body: string }): Promise<void> =>
ipcRenderer.invoke('app:notify', options),
// ---------- 开机自启与应用设置 ----------
/** 查询是否已设置开机自启 */
getAutoLaunch: (): Promise<boolean> => ipcRenderer.invoke('app:get-auto-launch'),
/** 设置开机自启,返回设置后的实际状态 */
setAutoLaunch: (enable: boolean): Promise<boolean> => ipcRenderer.invoke('app:set-auto-launch', enable),
/** 读取应用本地设置closeToTray 等) */
getAppSettings: (): Promise<{ closeToTray: boolean }> => ipcRenderer.invoke('app:get-settings'),
/** 增量更新应用本地设置,返回更新后的完整设置 */
setAppSettings: (patch: Partial<{ closeToTray: boolean }>): Promise<{ closeToTray: boolean }> =>
ipcRenderer.invoke('app:set-settings', patch),
// ---------- 文件下载 ----------
/** 下载文件:走主进程弹系统"另存为"对话框file:// 下 <a download> 跨域失效的替代方案) */
downloadFile: (url: string, fileName: string): Promise<void> =>
ipcRenderer.invoke('download:start', url, fileName),
/** 订阅下载完成事件state: completed/cancelled/interrupted返回取消订阅函数 */
onDownloadDone: (
callback: (payload: { state: string; fileName: string; savePath: string }) => void
): (() => void) => subscribe('download:done', callback),
/** 在系统文件管理器中显示指定文件(下载完成 toast 的"打开文件夹"操作) */
showItemInFolder: (fullPath: string): Promise<void> =>
ipcRenderer.invoke('shell:show-item-in-folder', fullPath),
// ---------- 应用内更新 ----------
/** 检查更新(结果通过 onUpdateStatus 推送) */
checkForUpdate: (): Promise<void> => ipcRenderer.invoke('updater:check'),
/** 开始下载更新包(进度通过 onUpdateStatus 推送) */
downloadUpdate: (): Promise<void> => ipcRenderer.invoke('updater:download'),
/** 退出并安装已下载的更新 */
quitAndInstall: (): Promise<void> => ipcRenderer.invoke('updater:install'),
/** 订阅更新状态事件checking/available/not-available/downloading/downloaded/error/dev */
onUpdateStatus: (callback: (payload: Record<string, unknown>) => void): (() => void) =>
subscribe('updater:status', callback),
}
contextBridge.exposeInMainWorld('electronAPI', electronAPI)