1.先创建vue项目
1.1安装脚手架
npm install -g @vue/cli
# OR
yarn global add @vue/cli
1.2创建项目
vue create electron-demo
2.安装electron (electron版本选择11)
vue add electron-builder
3.安装自动更新插件
npm install electron-updater --save
4.配置vue.config文件
module.exports = {
pluginOptions: {
electronBuilder: {
outputDir: "upms-dist",
nodeIntegration: true,
builderOptions: {
appId: "wltDemo.com", //应用id
productName: "upms", // 项目名,也是生成的安装文件名,即wyDemo.exe
copyright: "upms Copyright © 2022", // 版权信息
// 'files': [
// './**/*'
// ],
// 'directories': {
// 'output': './electronPack' // 输出文件路径
// },
extraResources:["./src/extraResources/**"],//打包托盘图标
publish: [
{
provider: "generic",
url: "http://192.168.0.100:8099/electron/",
// url: "http://127.0.0.1:8099/electron/",
},
],
win: {
// win相关配置
icon: "./src/assets/images/logo.png", // 窗口左上角图标256*256
requestedExecutionLevel: "requireAdministrator", //获取管理员权限
target: [
{
target: "nsis", // 利用nsis制作安装程序
arch: [
"x64", // 64位
"ia32",
],
},
],
},
nsis: {
oneClick: false, // 是否一键安装
allowElevation: true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
allowToChangeInstallationDirectory: true, // 允许修改安装目录
installerIcon: "./favicon.ico", // 安装图标
uninstallerIcon: "./favicon.ico", // 卸载图标
installerHeaderIcon: "./favicon.ico", // 安装时头部图标
createDesktopShortcut: true, // 创建桌面图标
createStartMenuShortcut: true, // 创建开始菜单图标
shortcutName: "upms", // 桌面图标名称(项目名称)
}
},
},
},
}
5.新建electron-update.js文件
import { autoUpdater, NoOpLogger } from "electron-updater";
import config from ".././package.json";
import { ipcMain, app, dialog } from "electron";
const logger = require("electron-log");
let mainWindow = null;
autoUpdater.autoDownload = false;
let canQuit = false;
let version=''
export function updateHandle(window, feedUrl) {
mainWindow = window;
let message = {
error: "检查更新出错",
checking: "正在检查更新……",
updateAva: "检测到新版本,正在下载……",
updateNotAva: "现在使用的就是最新版本,不用更新",
};
autoUpdater.setFeedURL(feedUrl);
autoUpdater.checkForUpdates();
//监听升级失败事件
autoUpdater.on("error", function (error) {
sendUpdateMessage({
cmd: "error",
message: error,
});
logger.error("监听系统升级事件失败");
});
//监听开始检测更新事件
autoUpdater.on("checking-for-update", function (message) {
sendUpdateMessage({
cmd: "checking-for-update",
message: message,
});
console.log("检查");
logger.info("开始监听系统升级事件");
});
//监听没有可用更新事件
autoUpdater.on("update-not-available", function (message) {
sendUpdateMessage({
cmd: "update-not-available",
message: message,
});
logger.info("没有发现新版本");
});
//监听发现可用更新事件
autoUpdater.on("update-available", function (message) {
version=message.version
sendUpdateMessage({
cmd: "update-available",
message: message,
});
autoUpdater.autoDownload = true;
logger.info("发现有新版本");
});
// 更新下载进度事件
autoUpdater.on("download-progress", function (progressObj) {
//事件没触发可能更新包已下载
sendUpdateMessage({
cmd: "download-progress",
message: progressObj,
});
logger.info("更新下载进度...");
});
autoUpdater.on("close", (event) => {
if (!canQuit) {
mainWindow.hide();
mainWindow.setSkipTaskbar(true);
event.preventDefault();
}
});
//监听下载完成事件
autoUpdater.on(
"update-downloaded",
function (event, releaseNotes, releaseName, releaseDate, updateUrl) {
logger.info("下载包成功");
sendUpdateMessage({
cmd: "update-downloaded",
message: {
releaseNotes,
releaseName,
releaseDate,
updateUrl,
},
});
// //退出并安装更新包
// if (process.platform !== "darwin") {
// canQuit = true;
// // autoUpdater.quitAndInstall();
// setImmediate(() => autoUpdater.quitAndInstall(true, true));
// logger.info('下载完成,退出并且安装更新包')
// }
app.whenReady().then(() => {
logger.info("下载提示");
let clickId = dialog.showMessageBoxSync({
type: "info",
title: "升级提示",
essage: `已为你升级到最新版V${version},是否立即体验`,
buttons: ["立即体验", "稍后体验"],
cancelId: 1,
});
if (clickId === 0) {
logger.info("下载完成,退出并且安装更新包");
canQuit = true;
setImmediate(() => autoUpdater.quitAndInstall(true, true));
} else {
sendUpdateMessage({
cmd: "update-await",
message: "稍后重启",
});
}
});
}
);
//接收渲染进程消息,开始检查更新
// ipcMain.on("checkForUpdate", (e, arg) => {
// //执行自动更新检查
// // sendUpdateMessage({cmd:'checkForUpdate',message:arg})
// if (arg) {
// autoUpdater.autoDownload = true;
// }
// console.log(e,arg,'hhhh');
// autoUpdater.checkForUpdates();
// });
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
mainWindow.webContents.send("message", text);
}
6.在主进程background中引入
"use strict";
import {
app,
protocol,
BrowserWindow,
BrowserView,
Tray,
Menu,
ipcMain,
webContents,
CommandLine,
} from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer";
const fs = require("fs");
import path from "path";
import { event } from "jquery";
import { updateHandle } from "@/electron-update.js";
const gotTheLock = app.requestSingleInstanceLock();
const isDevelopment = process.env.NODE_ENV !== "production";
import logger from "@/logFile"; //引入封装好的代码
var win;
let willQuitApp = false;
const { crashReporter } = require("electron");
app.setPath("crashDumps", "D:/crashe_log"); //在启动崩溃报告器之前覆盖该目录Crashpad
protocol.registerSchemesAsPrivileged([
{ scheme: "app", privileges: { secure: true, standard: true } },
]);
logger.info("启用日志");
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//false关闭web权限检查,允许跨域
webSecurity: false,
nodeIntegration: true,
nodeIntegrationInWorker: false, // 是否在Web工作器中启用了Node集成
// preload: path.join(__dirname, "../src/preload.js"),
preload: path.resolve(__dirname, "../src/extraResources/preload.js"),
contextIsolation: false,
show: false,
},
});
let view = new BrowserView();
win.setBrowserView(view);
view.setBounds({ x: 0, y: 0, width: 500, height: 500 });
if (process.env.WEBPACK_DEV_SERVER_URL) {
await view.webContents.loadURL(
process.env.WEBPACK_DEV_SERVER_URL + "/loading.html"
);
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
view.webContents.loadURL("app://./loading.html");
createProtocol("app");
win.loadURL("app://./index.html");
}
view.webContents.on("dom-ready", () => {
logger.info("开启加载页面");
win.show();
});
ipcMain.on("stop-loading-main", () => {
logger.info("关闭加载页面");
win.removeBrowserView(view);
});
win.on("close", (e) => {
if (willQuitApp) {
win = null;
} else {
e.preventDefault(); //阻止窗口的关闭事件
win.hide();
}
});
win.on("ready-to-show", () => {
// win.maximize()//窗口最大化
win.show();
});
updateHandle(win, "http://192.168.0.100:8099/electron/");
}
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("will-finish-launching", () => {
//应用启动
crashReporter.start({
productName: "crashDumps",
companyName: "crashDumps",
// submitURL: "http://192.168.0.100:8099/crash",
autoSubmit: true,
uploadToServer: true, //将崩溃报告发送给服务器
compress: true, //崩溃报告将压缩并上传,使用带有 Content-Encoding: gzip 的头部
});
});
app.on("activate", () => {
// process.crash();
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
app.on("before-quit", () => {
willQuitApp = true;
win.close();
});
if (!gotTheLock) {
app.quit();
} else {
app.on("second-instance", (event) => {
if (win.isMinimized()) win.restore();
win.show();
});
let appTray = null;
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();
// Menu.setApplicationMenu(null) // 隐藏菜单栏
appTray = new Tray(
path.resolve(__dirname, "../src/extraResources/logo.png")
);
appTray.on("click", () => {
console.log("click");
win.show();
});
appTray.on("right-click", () => {
let contextMenu = Menu.buildFromTemplate([
{
label: "退出",
click: app.quit,
},
]);
appTray.popUpContextMenu(contextMenu);
});
appTray.setToolTip("平台");
});
}
if (isDevelopment) {
if (process.platform === "win32") {
process.on("message", (data) => {
if (data === "graceful-exit") {
app.quit();
}
});
} else {
process.on("SIGTERM", () => {
app.quit();
});
}
}
//记录日志
ipcMain.handle("log", async (event, arg) => {
//与渲染进程通信
return new Promise((resolve, reject) => {
logger.info(arg);
});
});
process.on("uncaughtException", function (error) {
logger.info(error, "主进程异常");
// 上报异常
// 异常日志
});
7.APP.vue中告知主进程关闭预加载页面
beforeCreate() {
window.ipcRenderer.send("stop-loading-main");
}
8.预加载preload.js文件
const electron = require('electron');
window.ipcRenderer = require('electron').ipcRenderer;
后面渲染进程调用ipcRenderer ,通过window.ipcRenderer调用即可 无需从electron引入
9.logFile.js处理日志文件
import logger from 'electron-log'
import {app} from 'electron'
logger.transports.file.level = 'debug'
logger.transports.file.maxSize = 1002430 // 10M
logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}]{scope} {text}'
let date = new Date()
date = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
// logger.transports.file.file = app.getPath('userData') + '\\electron_log\\app\\' + date + '.log'
// 返回位置为日志位置 没有文件夹会自动创建
logger.transports.file.resolvePath = () => 'D:electron_log\\' + date + '.log';
export default {
info (param) {
logger.info(param)
},
warn (param) {
logger.warn(param)
},
error (param) {
logger.error(param)
},
debug (param) {
logger.debug(param)
},
verbose (param) {
logger.verbose(param)
},
silly (param) {
logger.silly(param)
}
}
文件目录