赞
踩
如果想美化安装流程,需访问以下地址,里面会提供两份二次打包所需代码文件,附带的有额外说明文档!
文章对应的项目地址
注意:修改主进程配置(electron所有配置文件)文件后,需关闭已运行的进程,再启动才会生效,关闭进程再重新启动项目即可看到效果
注意:electron 23 及以上的主版本不再支持Windows 7/8/8.1,如有需要,降低electron版本即可,原文地址: https://www.electronjs.org/zh/blog/windows-7-to-8-1-deprecation-notice
npm install -g electron
electron --version
npm
配置npm config get
disturl = "https://registry.npmmirror.com/-/binary/node"
electron_mirror = "https://registry.npmmirror.com/-/binary/electron/"
ELECTRON_MIRROR = "https://registry.npmmirror.com/-/binary/electron/"
registry = "https://registry.npmmirror.com/"
strict-ssl = false
npm config set disturl=https://registry.npmmirror.com/-/binary/node
npm config set electron_mirror=https://registry.npmmirror.com/-/binary/electron/
npm config set ELECTRON_MIRROR=https://registry.npmmirror.com/-/binary/electron/
git clone https://github.com/electron/electron-quick-start
gitee
搜electron-quick-start
,。会有跟github
同步更新的仓库,当然文章对应的项目地址里也会有基础模板,只是不会同步更新npm run start
menuConfig.js
文件-- menuConfig.js -- // 创建菜单模板 module.exports = { // process.platform 是 Node.js 提供的一个全局变量 'darwin':表示 macOS 系统 'win32':表示 Windows 系统 'linux':表示 Linux 系统 template: [ { label: '文件', submenu: [ { label: '打开', accelerator: 'Ctrl+O', click () { console.log("open") } }, { label: '保存' }, { type: 'separator' }, { label: '退出', role: 'quit' } ] }, { label: '编辑', submenu: [ { label: '撤销', role: 'undo' }, { label: '重做', role: 'redo' }, { type: 'separator' }, { label: '剪切', role: 'cut', accelerator: 'CmdOrCtrl+X', }, { label: '复制', role: 'copy' }, { label: '粘贴', role: 'paste' }, { label: '删除', role: 'delete' }, { type: 'separator' }, { label: '全选', role: 'selectAll' } ] }, { label: '查看', submenu: [{ label: '重载', accelerator: (function () { if (process.platform === 'darwin') { return 'Ctrl+Command+A' } else { return 'F5' } })(), click: function (item, focusedWindow) { // if (focusedWindow) { // // 重载之后, 刷新并关闭所有的次要窗体 // if (focusedWindow.id === 1) { // BrowserWindow.getAllWindows().forEach(function (win) { // if (win.id > 1) { // win.close() // } // }) // } focusedWindow.reload() // } } }, { label: '切换开发者工具', accelerator: (function () { // 判断是否是macOS系统 if (process.platform === 'darwin') { return 'Alt+Command+I' } else { return 'Ctrl+Shift+I' } })(), click: function (item, focusedWindow) { if (focusedWindow) { focusedWindow.toggleDevTools() } } }, { type: 'separator' }, { label: '应用程序菜单演示', click: function (item, focusedWindow) { if (focusedWindow) { const options = { type: 'info', title: '应用程序菜单演示', buttons: ['好的'], message: '此演示用于 "菜单" 部分, 展示如何在应用程序菜单中创建可点击的菜单项.' } dialog.showMessageBox(focusedWindow, options, function () { }) } } }] }, { label: '窗口', role: 'window', submenu: [{ label: '最小化', accelerator: 'CmdOrCtrl+M', role: 'minimize' }, { label: '关闭', accelerator: 'CmdOrCtrl+W', role: 'close' }, { type: 'separator' }, { label: '重新打开窗口', accelerator: 'CmdOrCtrl+Shift+T', enabled: false, // 是否禁用 false 禁用 true key: 'reopenMenuItem', click: function () { app.emit('activate') } }] }, { label: '帮助', submenu: [ { label: '关于', click: function () { shell.openExternal('http://electron.atom.io') } } ] } ], }
-- main.js --
const { app, BrowserWindow, Menu } = require('electron')
const { template } = require('./menuConfig');
// 创建菜单对象
const menu = Menu.buildFromTemplate(template);
// 设置应用程序菜单
Menu.setApplicationMenu(menu);
electron
项目的根目录-- main.js --
// 我的打包后的文件名叫 vue-dist 根据自己的文件名自行修改
global.__static = path.join(__dirname, '/vue-dist').replace(/\\/g, '\\\\')
mainWindow.loadURL(`${global.__static}/index.html`)
// global.__static = path.join(__dirname, '/vue-dist').replace(/\\/g, '\\\\')
// mainWindow.loadURL(`${global.__static}/index.html`)
-- 变成 --
// 根据自己的本地地址修改
mainWindow.loadURL('http://localhost:8001')
// 加载应用程序
if (!app.isPackaged) {
// 读取文件url地址 - 开发用 生产环境 返回true ,否则返回false
mainWindow.loadURL('http://localhost:8001')
} else {
// 读取本地文件地址 - 打包用
global.__static = path.join(__dirname, '/vue-dist').replace(/\\/g, '\\\\')
mainWindow.loadURL(`${global.__static}/index.html`)
}
// 开发用
// mainWindow.loadURL('http://localhost:8001')
// 打包用
global.__static = path.join(__dirname, '/vue-dist').replace(/\\/g, '\\\\')
mainWindow.loadURL(`${global.__static}/index.html`)
package.json
文件自定义打包命令// electron 打包出来的项目名, platform=win32 windows 系统, --arch=x64 系统版本, --icon 图标路径, --out打包后输出文件路径, app-version=0.0.1 版本号
"package": "electron-packager . electron --platform=win32 --arch=x64 --icon=./icon/icon.ico --out=./out-dist --asar --app-version=0.0.1 --overwrite --ignore=node_modules"
"scripts": {
"start": "electron .",
"package": "electron-packager . electron --platform=win32 --arch=x64 --icon=./icon/icon.ico --out=./out-dist --asar --app-version=0.0.1 --overwrite --ignore=node_modules"
},
npm run package
// 如果报错 Cannot find module 'electron,更新下包即可, 更新后再执行 npm run package
// npm initall
// npm run package
out-dist/electron-win32-x64
中找到已经打包好的exe文件,双击执行即可。electron-builder.json
文件{ "appId": "exe-dome.example.myapp", // 指定应用程序的唯一标识符,通常使用逆域名表示,用于在不同平台上标识应用程序 "productName": "exe-dist", // 指定生成的安装程序的名称。 "directories": { "output": "exe-dist" // 指定输出目录,即生成的安装程序的存放位置。 }, "win": { "target": "nsis", // 指定打包的目标格式为 NSIS(Nullsoft Scriptable Install System)安装程序。 "icon": "./icon/icon.jpg", // 指定应用程序的图标文件路径。 "artifactName": "${productName} Setup ${version}.${ext}" // 指定生成的安装程序的文件名格式 ${productName} 会被替换为应用程序名称,${version} 会被替换为应用程序版本号,${ext} 会被替换为文件扩展名。 }, "nsis": { "oneClick": false, // 禁用一键安装模式,用户需要手动选择安装选项。 "perMachine": true, // 将安装程序安装为所有用户,而不是当前用户。 "allowToChangeInstallationDirectory": true // 允许用户选择安装目录。 } }
npm i electron-builder -D
package.json
文件自定义打包命令// "build": "electron-builder"
"scripts": {
"start": "electron .",
"package": "electron-packager . electron --platform=win32 --arch=x64 --icon=./icon/icon.ico --out=./out-dist --asar --app-version=0.0.1 --overwrite --ignore=node_modules",
"build": "electron-builder"
},
注意:每次打包前建议确认上一次打包出来的文件已被手动删除,如果还存在,那么将其手动删除后再打包
npm run build
exe-dist
文件夹即可找到exe程序,双击执行即可出现安装程序注意:安装后,此exe程序是真实安装到了电脑上,并会生成注册表文件,需手动卸载。
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
frame: false, // 指定是否显示窗口的默认菜单项。设置为 true 表示显示,默认为 true。
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
width: 1200, // 窗口宽度 height: 600, // 窗口高度 // minWidth: 800, // 窗口的最小宽度。 // minHeight:600, // 窗口的最小高度。 // maxWidth:800, // 窗口的最大宽度。 // maxHeight:600, // 窗口的最大高度。 // x: 0, // 窗口的横坐标(以像素为单位),默认为屏幕的中心。 // y: 0, // 窗口的纵坐标(以像素为单位),默认为屏幕的中心。 frame: true, // 指定是否显示窗口的默认菜单项。设置为 true 表示显示,默认为 true。 transparent: false, // 指定窗口是否透明,默认为 false。 // backgroundColor: 'pink', // 窗口的背景颜色,可以使用颜色名称、HEX 值或 RGB 值进行设置。 title: "exe", // 窗口的标题,优先级低于加载文件。 // icon: "./icon/icon.jpg", // 窗口的图标路径。 show: true, // 指定窗口创建后是否立即显示,默认为 true。 resizable: true, // 指定窗口是否可以调整大小 center: true, // 指定窗口是否在屏幕中居中,默认为 true。 movable: true, // 指定窗口是否可以移动,默认为 true。 minimizable: true, // 指定窗口是否可以最小化,默认为 true。 maximizable: true, // 指定窗口是否可以最大化,默认为 true。 closable: true,//指定窗口是否可以关闭,默认为 true。 fullscreenable: true, // 指定窗口是否可以进入全屏模式,默认为 true。 alwaysOnTop: false, // 指定窗口是否始终在其他窗口之上,默认为 false。 fullscreen: false, // 指定窗口是否可以进入全屏模式,默认为 true -- 会导致最小化/半屏/关闭按钮隐藏。 webPreferences: { preload: path.join(__dirname, 'preload.js') }
preload.js
文件-- preload.js -- /** * The preload script runs before. It has access to web APIs * as well as Electron's renderer process modules and some * polyfilled Node.js functions. * * https://www.electronjs.org/docs/latest/tutorial/sandbox */ window.addEventListener('DOMContentLoaded', () => { const replaceText = (selector, text) => { const element = document.getElementById(selector) if (element) element.innerText = text } for (const type of ['chrome', 'node', 'electron']) { replaceText(`${type}-version`, process.versions[type]) } }) const { contextBridge, ipcRenderer } = require("electron") //向渲染进程(vue)暴露一些属性和方法 contextBridge.exposeInMainWorld('versions', { // 最小化 / 最小化到系统托盘 minimize(val) { ipcRenderer.send('minimize', val) }, // 窗口最大化 windowStatus() { ipcRenderer.send('windowStatus') }, // 关闭当前窗口 closeWin() { ipcRenderer.send('closeWin') }, })
/src
下创建header.vue
文件,并引入到App.vue中挂载(我这是示例,写的随意而已。)header.vue
加入以下代码 ------- 此时已添加拖拽窗口方法 css代码中的 -webkit-app-region: drag;
与-webkit-app-region: no-drag;
<template> <div class="header"> <el-tooltip class="item" effect="dark" content="最小化到系统托盘" placement="bottom"> <span class="no-drag el-icon-circle-close" @click="addMinimize(false)"></span> </el-tooltip> <el-tooltip class="item" effect="dark" content="最小化" placement="bottom"> <span class="no-drag el-icon-minus" @click="addMinimize(true)"></span> </el-tooltip> <el-tooltip class="item" effect="dark" :content="windowStatus ? '窗口化' : '全屏'" placement="bottom"> <span class="no-drag" :class="windowStatus ? 'el-icon-copy-document' : 'el-icon-full-screen'" @click="addWindowStatus"></span> </el-tooltip> <el-tooltip class="item" effect="dark" content="关闭程序" placement="bottom"> <span class="no-drag el-icon-close" @click="addCloseWin"></span> </el-tooltip> </div> </template> <script> // 来源根目录 preload.js const versions = window.versions; // electron 暴漏的主进程事件 export default { data () { return { versions, // 主进程暴漏的事件集合 具体看根目录preload.js文件 windowStatus: false, // 窗口化 true 全屏 false 窗口化 }; }, mounted () { }, methods: { // 最小化 / 最小化到系统托盘 addMinimize (stata) { // true 最小化 false 最小化到系统托盘 versions.minimize(stata); }, // 窗口最大化/还原 addWindowStatus () { // 窗口状态切换后 -- 切换图标 this.windowStatus = !this.windowStatus; versions.windowStatus(); }, addCloseWin () { versions.closeWin(); }, }, }; </script> <style lang="less"> .header { background-color: pink; text-align: right; // 鼠标拖拽 -webkit-app-region: drag; span { padding: 5px 0; font-size: 20px; margin-right: 20px; color: red; } } .no-drag { // 禁止拖拽 -webkit-app-region: no-drag; } </style>
-- main.js -- const { ipcMain } = require('electron/main') let mainWindow function createWindow () { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600, frame: false, // 指定是否显示窗口的默认菜单项。设置为 true 表示显示,默认为 true。 webPreferences: { preload: path.join(__dirname, 'preload.js') } }) // 以下事件来源 preload.js // 最小化窗口 ipcMain.on('minimize', (ev, val) => { // true 最小化 false 最小化到系统托盘 if (val) { mainWindow.minimize(); } else { // mainWindow.hide(); } }) // 窗口最大化/还原窗口 ipcMain.on('windowStatus', (ev, val) => { // 判断当前窗口状态 true 最大化 if (mainWindow.isMaximized()) { mainWindow.restore(); // 还原窗口大小 } else { mainWindow.maximize(); // 最大化窗口 } }) // 关闭当前窗口 ipcMain.on('closeWin', (ev, val) => { mainWindow.close(); })
ipcMain.on('minimize', (ev, val) => { // true 最小化 false 最小化到系统托盘 if (val) { mainWindow.minimize(); } else { // mainWindow.hide(); } }) --- 变为 --- ipcMain.on('minimize', (ev, val) => { // true 最小化 false 最小化到系统托盘 if (val) { mainWindow.minimize(); } else { mainWindow.hide(); } })
const { app, BrowserWindow, Menu, Tray, shell } = require('electron') app.whenReady().then(() => { let tray = null; // 设置最小化到系统托盘后的图标 tray = new Tray(path.join(__dirname, './icon/icon.jpg')); // 设置最小化到系统托盘后的小菜单 const contextMenu = Menu.buildFromTemplate([ { label: '打开应用', click: () => { mainWindow.show(); } }, { label: '项目地址', click: () => { shell.openExternal('https://gitee.com/kuxiao-smile/exe-demo'); } }, { type: 'separator' }, { label: '退出', click: () => { app.quit(); } } ]); // 设置最小化到系统托盘后的悬浮名 tray.setToolTip('我的应用'); // 将设置的小菜单 加入菜单模板 tray.setContextMenu(contextMenu); // 系统托盘小图标点击事件 tray.on('click', () => { mainWindow.show(); // 点击系统托盘图标时打开应用程序 }); // 创建窗口 createWindow() app.on('activate', function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow() }) })
ctrl+shift+I
,即可打开控制台,但如果想使用Vue扩展就得进行额外配置app.whenReady().then(async () => { // 创建窗口 createWindow() app.on('activate', async () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow() }) // 判断是否生产环境 // 读取本地浏览器扩展,并添加到控制台 -- 非必要不要使用,会导致浏览器本来装的扩展文件损坏 if (!app.isPackaged) { // 开发环境启用 vue-devtools 扩展 /nhdogjmejiglipccpnnnanhbledajbpd/6.5.0_0 / 扩展ID/版本号自行修改 const vueDevToolsPath = path.join( os.homedir(), '/AppData/Local/Google/Chrome/User Data/Default/Extensions/nhdogjmejiglipccpnnnanhbledajbpd/6.5.0_0' ) await session.defaultSession.loadExtension(vueDevToolsPath) } })
const { execFile } = require('child_process'); app.whenReady().then(async () => { // 创建窗口 createWindow() app.on('activate', async () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow() }) // 执行外部脚本处理文件 -- 无需要 - 可注释 execFile(path.join(__dirname, '/微信多开.bat').replace(/\\/g, '\\\\'), (error, stdout, stderr) => { if (error) { console.error(`执行批处理文件时出错:${error.message}`); return; } console.log('批处理文件执行成功'); console.log('标准输出:', stdout); console.error('错误输出:', stderr); });})
// 根据自己的微信路径自行修改,改完把文件后缀改成bat即可
start D:\WeChat\WeChat.exe
start D:\WeChat\WeChat.exe
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。