diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 5b54e20..1fd50fc 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -1,13 +1,13 @@ import { resolve } from 'path' -import { defineConfig, externalizeDepsPlugin } from 'electron-vite' +import { defineConfig, externalizeDepsPlugin, bytecodePlugin } from 'electron-vite' import react from '@vitejs/plugin-react' export default defineConfig({ main: { - plugins: [externalizeDepsPlugin()] + plugins: [externalizeDepsPlugin(), bytecodePlugin()] }, preload: { - plugins: [externalizeDepsPlugin()] + plugins: [externalizeDepsPlugin(), bytecodePlugin()] }, renderer: { resolve: { diff --git a/package.json b/package.json index c08a5b0..381aa5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cvpilot-desktop", - "version": "1.0.0", + "version": "1.0.3", "description": "An Electron application with React and TypeScript", "main": "./out/main/index.js", "author": "example.com", @@ -12,7 +12,7 @@ "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false", "typecheck": "npm run typecheck:node && npm run typecheck:web", "start": "electron-vite preview", - "dev": "electron-vite dev", + "dev": "electron-vite dev --watch", "build": "npm run typecheck && electron-vite build", "postinstall": "electron-builder install-app-deps", "build:unpack": "npm run build && electron-builder --dir", diff --git a/src/main/index.ts b/src/main/index.ts index e991ce2..dd1520b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,8 +2,9 @@ import { app, shell, BrowserWindow } from 'electron' import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/icon.png?asset' -import { setupSignals } from './ipc' +import { setupIpcHandle } from './ipc' import './sqlite3' +import { setupAutoUpdater } from './updater' function createWindow(): void { // Create the browser window. @@ -35,6 +36,9 @@ function createWindow(): void { } else { mainWindow.loadFile(join(__dirname, '../renderer/index.html')) } + + setupIpcHandle() + setupAutoUpdater(mainWindow) } // This method will be called when Electron has finished @@ -51,8 +55,6 @@ app.whenReady().then(() => { optimizer.watchWindowShortcuts(window) }) - setupSignals() - createWindow() app.on('activate', function () { diff --git a/src/main/ipc.ts b/src/main/ipc.ts index b3be882..a796c42 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -1,8 +1,16 @@ -import { ipcMain } from 'electron' +import { autoUpdater, ipcMain } from 'electron' /** * ipc signals */ -export const setupSignals = (): void => { +export const setupIpcHandle = (): void => { ipcMain.on('ping', () => console.log('pong')) + ipcMain.handle('check-for-updates', (event) => { + console.log('检查更新') + autoUpdater.checkForUpdates() + }) + + ipcMain.handle('quit-and-install', () => { + autoUpdater.quitAndInstall() + }) } diff --git a/src/main/sqlite3.ts b/src/main/sqlite3.ts index a501d88..41b4122 100644 --- a/src/main/sqlite3.ts +++ b/src/main/sqlite3.ts @@ -12,14 +12,19 @@ const initKnex = (): Knex => useNullAsDefault: true }) -// 创建一个表 +// 创建一个表,如果它不存在 const createTable = async (db: Knex) => { - await db.schema.createTable('users', (table) => { - table.increments('id') - table.string('name') - table.integer('age') - }) - console.log('Table created') + const exists = await db.schema.hasTable('users') + if (!exists) { + await db.schema.createTable('users', (table) => { + table.increments('id') + table.string('name') + table.integer('age') + }) + console.log('Table created') + } else { + console.log('Table already exists') + } } // 插入数据 diff --git a/src/main/updater.ts b/src/main/updater.ts new file mode 100644 index 0000000..da11828 --- /dev/null +++ b/src/main/updater.ts @@ -0,0 +1,38 @@ +import { app, BrowserWindow, ipcMain } from 'electron' +import { autoUpdater } from 'electron-updater' + +/** + * 文档地址: https://www.electronjs.org/zh/docs/latest/api/auto-updater#event--before-quit-for-update + */ +export const setupAutoUpdater = (win: BrowserWindow) => { + // 配置更新服务器地址 + const updateServerUrl = `http://192.168.1.7:5500/update/${process.platform}/${app.getVersion()}` + console.log(app.getVersion()) + // 设置自动更新的 feed URL + autoUpdater.setFeedURL({ provider: 'generic', url: updateServerUrl }) + + console.log(autoUpdater.getFeedURL()) + + autoUpdater.on('update-downloaded', (e) => { + console.log(e) + ipcMain.emit('update-ready', e) + }) + + autoUpdater.on('update-not-available', () => { + console.log('update-not-available') + ipcMain.emit('update-not-available', '没有可用更新') + }) + + autoUpdater.on('checking-for-update', () => { + console.log('checking-for-update,开始检查更新') + }) + + autoUpdater.on('update-available', () => { + console.log('update-available,有可用更新') + }) + + autoUpdater.on('error', (error) => { + console.log('更新错误', error) + win.webContents.send('update-error', { error, updateServerUrl }) + }) +} diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index a153669..a840fa4 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -3,6 +3,10 @@ import { ElectronAPI } from '@electron-toolkit/preload' declare global { interface Window { electron: ElectronAPI - api: unknown + api: { + checkUpdate + confirmUpdate + quitInstall + } } } diff --git a/src/preload/index.ts b/src/preload/index.ts index 2d18524..b8d67ba 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -1,8 +1,12 @@ -import { contextBridge } from 'electron' +import { contextBridge, ipcRenderer } from 'electron' import { electronAPI } from '@electron-toolkit/preload' // Custom APIs for renderer -const api = {} +const api = { + checkUpdate: () => ipcRenderer.invoke('check-for-updates'), + confirmUpdate: (version) => ipcRenderer.invoke('confirmUpdate', version), + quitInstall: () => ipcRenderer.invoke('quit-and-install') +} // Use `contextBridge` APIs to expose Electron APIs to // renderer only if context isolation is enabled, otherwise diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index af20fb6..18d5d3e 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -1,12 +1,36 @@ import Versions from './components/Versions' import electronLogo from './assets/electron.svg' +import { useEffect } from 'react' function App(): JSX.Element { const ipcHandle = (): void => window.electron.ipcRenderer.send('ping') + const updateHandle = () => window.api.checkUpdate() + + useEffect(() => { + window.electron.ipcRenderer.on('update-ready', (e, data) => { + console.log(data) + const response = confirm('新版本已下载,是否重启应用来安装更新?') + if (response) window.api.quitInstall() + }) + }, []) + + useEffect(() => { + window.electron.ipcRenderer.on('update-error', (e, data) => { + // console.log(e) + console.log(data) + }) + }, []) + + useEffect(() => { + window.electron.ipcRenderer.on('update-not-available', (e, data) => { + console.log(data) + }) + }, []) return ( <> logo +
Powered by electron-vite
Build an Electron app with React diff --git a/src/renderer/src/components/Versions.tsx b/src/renderer/src/components/Versions.tsx index dac185f..5bd4b41 100644 --- a/src/renderer/src/components/Versions.tsx +++ b/src/renderer/src/components/Versions.tsx @@ -8,6 +8,7 @@ function Versions(): JSX.Element {
  • Electron v{versions.electron}
  • Chromium v{versions.chrome}
  • Node v{versions.node}
  • +
  • {window.electron.process.platform}
  • ) } diff --git a/src/renderer/src/main.tsx b/src/renderer/src/main.tsx index f4d40c7..9633297 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/src/main.tsx @@ -1,11 +1,5 @@ import './assets/main.css' - -import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' -ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - - - -) +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render()