# hx-electron **Repository Path**: code_yu/hx-electron ## Basic Information - **Project Name**: hx-electron - **Description**: 快速搭建 electron ,vue环境,实现自动更新,集成了sqlite数据库 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 19 - **Forks**: 3 - **Created**: 2020-09-20 - **Last Updated**: 2025-09-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README @[TOC](electron 打包,自动更新,修改默认安装目录) # 使用 ## 克隆项目 ``` git clone https://gitee.com/code_yu/hx-electron.git cd hx-electron ``` ## 安装依赖 ``` yarn install ``` ### 开发环境启动 ``` yarn electron:serve ``` ### 正式打包 ``` yarn electron:build ``` ### 安装问题 sqlite3、electron 安装失败,一般是国内网络问题,用梯子安装依赖一般都没有问题。 # 技术栈 文档 - [Electron](https://www.electronjs.org/docs/all) - [Vue3](https://v3.cn.vuejs.org/) JavaScript 框架 - [element-plus UI](https://element-plus.gitee.io/zh-CN/component/button.html) 优秀的前端UI组件 - [vue-config-js](https://cli.vuejs.org/zh/config/#vue-config-js) vue.config.js 配置 - [vue-cli-plugin-electron-builder](https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/guide.html#table-of-contents) 打包工具 - [nsis](https://www.electron.build/configuration/nsis) 打包配置 - [electron-updater](https://www.electron.build/auto-update) 应用自动更新 - [electron-log](https://github.com/megahertz/electron-log) > 如需查看打包后应用的日志,那么需从命令行启动应用 ``` shell $ cd demo_path $ ./demo.exe ```` # 应用自动更新 ### 1. 配置 `vue.config.js` 中的应用更新服务器地址 详细打包配置请看 [vue.config.js 完整示例](#other-1) ``` javascript module.exports = { pluginOptions: { electronBuilder: { ... publish: [ { provider: 'generic', url: 'http://127.0.0.1/app/' } ] ... } } } } ``` ### 2. 在主进程写更新应用逻辑 在 `background.js` 文件或 `main.js` 中写入更新逻辑 以下为 `background.js` 完整示例: ``` javascript 'use strict' import { app, protocol, BrowserWindow, Menu, dialog } from 'electron' import { createProtocol } from 'vue-cli-plugin-electron-builder/lib' import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer' const { autoUpdater } = require('electron-updater') const path = require('path') const log = require('electron-log') const isDevelopment = process.env.NODE_ENV !== 'production' let win protocol.registerSchemesAsPrivileged([ { scheme: 'app', privileges: { secure: true, standard: true } } ]) log.info('启用日志') function createWindow () { Menu.setApplicationMenu(null) // Create the browser window. win = new BrowserWindow({ width: 1400, height: 800, webPreferences: { nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION, preload: path.join(__dirname, 'preload.js') } }) if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) if (!process.env.IS_TEST) win.webContents.openDevTools() } else { createProtocol('app') // Load the index.html when not in development win.loadURL('app://./index.html') autoUpdater.checkForUpdates() } win.on('closed', () => { win = null }) } app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (win === null) { createWindow() } }) app.on('ready', async () => { if (isDevelopment && !process.env.IS_TEST) { // Install Vue Devtools try { await installExtension(VUEJS_DEVTOOLS) } catch (e) { console.error('Vue Devtools failed to install:', e.toString()) } } createWindow() }) // Exit cleanly on request from parent process in development mode. if (isDevelopment) { if (process.platform === 'win32') { process.on('message', (data) => { if (data === 'graceful-exit') { app.quit() } }) } else { process.on('SIGTERM', () => { app.quit() }) } } // ====================================================================== // 更新模块 // ====================================================================== if (!process.env.WEBPACK_DEV_SERVER_URL) { autoUpdater.autoDownload = false autoUpdater.signals.updateDownloaded(() => {}) autoUpdater.on('error', (error) => { log.warn('检查更新失败: ' + error == null ? 'unknown' : (error.stack || error).toString()) // dialog.showErrorBox('Error: ', error == null ? 'unknown' : (error.stack || error).toString()) }) autoUpdater.on('update-available', (info) => { // var appInfo = { // info: info.version, // files: info.files, // path: info.path, // sha512: info.sha512, // releaseDate: info.releaseDate // } dialog.showMessageBox({ type: 'info', title: '更新提示', message: '软件需要更新,您是否立即更新?', buttons: ['推迟', '立即更新'] }).then((res) => { log.warn('index:' + res.response) if (res.response === 1) { log.warn('选择升级') autoUpdater.downloadUpdate() } else { log.warn('选择不升级:') } }) }) // 检查更新时触发 autoUpdater.on('update-available', (res) => { log.warn('检查更新时触发') // log.warn(res) // dialog.showMessageBox({ // title: '检查更新', // message: '正在检查更新' // }) }) // 没有可用更新 autoUpdater.on('update-not-available', () => { log.warn('没有可用更新') // dialog.showMessageBox({ // title: '已是最新版', // message: '当前版本是最新版本。' // }) }) // 安装更新 autoUpdater.on('update-downloaded', (res) => { // log.warn(res) log.warn('下载完毕!提示安装更新') dialog.showMessageBox({ title: '升级提示!', message: '已自动升级为最新版,请重启应用!' }, () => { log.warn('确认安装') setImmediate(() => autoUpdater.quitAndInstall(true, true)) }) }) // 下载进度 // autoUpdater.on('download-progress', (event) => { // log.warn(event.percent) // }) } ``` ### 3. 打包一个应用(v1.0.0) 打包后 `dist_electron` 目录中有 `*.blockmap` 格式的文件; 将文件复制到 '更新服务器' (http://127.0.0.1/app/) 目录下; ### 4. 打包一个升级版的应用(v1.1.0) 打包后 `dist_electron` 有如下三个文件: - `新版本安装包.exe` - `新版本_v1.1.0.blockmap`, - `latest.yml` 将上面三个文件复制到 ‘更新服务器’ (http://127.0.0.1/app/) 目录下; 以后每次有更新就复制这三个文件至 ‘更新服务器’,保留旧版本的 `*.blockmap` 文件,旧版本的应用的执行文件(`.exe`)可以删除。 # 其他 ## 打包 ### 打包配置 vue.config.js 完整示例 ``` javascript module.exports = { pluginOptions: { electronBuilder: { // 预加载文件 preload: 'src/preload.js', // 渲染进程也可以获取原生node包 nodeIntegration: true, // 打包配置 builderOptions: { // 发布者名称 productName: 'hx-admin', // 包名 appId: 'cn.xxx.hxadmin', copyright: 'hui xian copyright', // 更新的服务器 publish: [ { provider: 'generic', url: 'http://127.0.0.1/app/' } ], asar: false, // 不需要打包至asar中的文件如数据库文件,icons文件 extraResources: [ { from: './data/db.db', to: '../data/db.db', filter: ['**/*'] }, './icons'], win: { // 图标文件大小为 256*256 icon: './icons/icon.ico', target: [ { target: 'nsis', arch: [ // 'x64', 'ia32' ] } ], // 打包权限 asInvoker | highestAvailable requestedExecutionLevel: 'highestAvailable' }, // 安装包名称,可自行配置 artifactName: '${productName}_Setup_${version}_${platform}.${ext}', nsis: { // 一键安装,如果设为true,nsis设置就无意义请直接删除 nsis 配置 oneClick: false, // true全用户安装【目录为:C:\Program Files (x86)】,false安装到当前用户 perMachine: true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。 allowElevation: true, // 允许修改安装目录 allowToChangeInstallationDirectory: true, // 创建桌面图标 createDesktopShortcut: true, // 创建开始菜单图标 createStartMenuShortcut: true, // 快捷方式的名称,默认为应用程序名称 // shortcutName: 'HX', // 安装图标 installerIcon: './icons/icon.ico', // 卸载图标 uninstallerIcon: './icons/icon.ico', // 安装时头部图标 installerHeaderIcon: './icons/icon.ico', // 配置 nsn 如修改默认安装目录 include: './installer.nsh' } } } } } ``` ### 安装时修改默认目录 #### 1. 在 nsis 添加 `include` 属性: > 详细打包配置请看 [vue.config.js 完整示例](#other-1) ``` javascript module.exports = { pluginOptions: { electronBuilder: { ... nsis: { // 配置 nsn 如修改默认安装目录 include: './installer.nsh' ... } ... } } } } ``` #### 2. 根目录新建 `installer.nsh` 文件,内容如下: >`installer.nsh` 一般和`vue.config.js`为同级目录 > `D:\Program Files (x86)` 为定义安装目录,可修改 > `${PRODUCT_NAME}` 为应用名称变量,一般没不需要改 ``` !macro preInit SetRegView 64 WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "D:\Program Files\${PRODUCT_NAME}" WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "D:\Program Files\${PRODUCT_NAME}" SetRegView 32 WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "D:\Program Files (x86)\${PRODUCT_NAME}" WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "D:\Program Files (x86)\${PRODUCT_NAME}" !macroend ``` --- ## 使用自定义的 `svg` 图标 1. 在[iconfont](https://www.iconfont.cn/)下载`.svg`图标; 2. 将下载的`.svg`文件放置 `/src/icons/svg` 目录下; 3. 执行压缩svg文件的指令 `yarn svgo` ;