Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的。
检查Electron是否正在开发中运行
const electron = require("electron");
const isDev = !electron.app.isPackaged
实现自动更新
使用 electron-builder
结合 electron-updater
实现自动更新。
主进程添加自动更新检测和事件监听:
import { autoUpdater } from "electron-updater"
import { ipcMain } from "electron"
function updateHandle() {
let message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载……',
updateNotAva: '现在使用的就是最新版本,不用更新',
};
autoUpdater.setFeedURL('https://xxx.xxxx.com/');
autoUpdater.on('error', function (error) {
console.log(error)
sendUpdateMessage(message.error)
});
autoUpdater.on('checking-for-update', function () {
sendUpdateMessage(message.checking)
});
autoUpdater.on('update-available', function (info) {
sendUpdateMessage(message.updateAva)
});
autoUpdater.on('update-not-available', function (info) {
sendUpdateMessage(message.updateNotAva)
});
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
mainWindow.webContents.send('downloadProgress', progressObj)
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
ipcMain.on('isUpdateNow', (e, arg) => {
console.log(arguments);
console.log("开始更新");
//some code here to handle event
autoUpdater.quitAndInstall();
});
mainWindow.webContents.send('isUpdateNow')
});
ipcMain.on("checkForUpdate",()=> {
//执行自动更新检查
autoUpdater.checkForUpdates();
})
}
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
在视图(View)层中触发自动更新,并添加自动更新事件的监听。
触发自动更新:
ipcRenderer.send("checkForUpdate");
监听自动更新事件:
ipcRenderer.on("message", (event, text) => {
console.log(text)
});
ipcRenderer.on("downloadProgress", (event, progressObj)=> {
console.log(progressObj.percent)
this.setState({
downloadPercent: parseInt(progressObj.percent) || 0
})
});
ipcRenderer.on("isUpdateNow", () => {
ipcRenderer.send("isUpdateNow");
});
为避免多次切换页面造成监听的滥用,切换页面前必须移除监听事件:
ipcRenderer.removeAll(["message", "downloadProgress", "isUpdateNow"]);
使用 electron-builder
打包配置
electron-builder.yaml文件配置如下
directories:
buildResources: buildResources
output: dist
appId: cube.create-desktop
productName: "Create 3"
publish: # empty provider list = don't publish
mac:
category: public.app-category.education
entitlements: buildResources/entitlements.mac.plist
extendInfo:
NSCameraUsageDescription: >-
This app requires camera access when using the video sensing blocks.
NSMicrophoneUsageDescription: >-
This app requires microphone access when recording sounds or detecting loudness.
gatekeeperAssess: true
hardenedRuntime: true
icon: buildResources/CreateDesktop.icns
provisioningProfile: embedded.provisionprofile
artifactName: "Create ${version}.${ext}"
target:
- dmg
- mas
dmg:
title: "Create ${version}"
mas:
category: public.app-category.education
entitlements: buildResources/entitlements.mas.plist
entitlementsInherit: buildResources/entitlements.mas.inherit.plist
hardenedRuntime: false
icon: buildResources/CreateDesktop.icns
masDev:
type: development
provisioningProfile: mas-dev.provisionprofile
win:
icon: buildResources/CreateDesktop.ico
target:
- appx
- nsis
appx:
identityName: CreateFoundation.CreateDesktop
publisherDisplayName: "Create Foundation"
publisher: "CN=2EC43DF1-469A-4119-9AB9-568A0A1FF65F"
artifactName: "Create ${version} ${arch}.${ext}"
nsis:
oneClick: false # allow user to choose per-user or per-machine
artifactName: "Create ${version} Setup.${ext}"
限制开启一个electron实例
app.requestSingleInstanceLock()
方法的返回值表示你的应用程序实例是否成功取得了锁。 如果它取得锁失败,你可以假设另一个应用实例已经取得了锁并且仍旧在运行,并立即退出。
即: 如果当前进程是应用程序的主要实例,则此方法返回true
,同时你的应用会继续运行。 如果当它返回 false
如果你的程序没有取得锁,它应该立刻退出,并且将参数发送给那个已经取到锁的进程。
在 macOS 上, 当用户尝试在 Finder 中打开您的应用程序的第二个实例时, 系统会通过发出 open-file
和 open-url
事件来自动强制执行单个实例,。 但是当用户在命令行中启动应用程序时, 系统的单实例机制将被绕过, 您必须手动调用此方法来确保单实例。
在第二个实例启动时激活主实例窗口的示例:
const { app } = require('electron')
let myWindow = null
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到myWindow这个窗口
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore()
myWindow.focus()
}
})
// 创建 myWindow, 加载应用的其余部分, etc...
app.whenReady().then(() => {
myWindow = createWindow()
})
}
windows平台 serialport
串口编译
如果需要serialport作为Electron项目的依赖项,则必须针对项目使用的Electron版本对其进行编译。
对于大多数最常见的用例(标准处理器平台上的Linux,Mac,Windows),我们使用prebuild来编译和发布库的二进制文件。 使用nodejs进行编译node-gyp需要使用Python 2.x,因此请确保已安装它,并且在所有操作系统的路径中。Python 3.x无法正常工作。
安装windows构建工具和配置想省时省力请选择以下方案:
npm install --global --production windows-build-tools
上边命令决定串口编译是否成功。安装过程非常缓慢,安装完成就等于串口编译成功了99%。
手动安装工具和配置请看github.com/nodejs/node…
接下来用 electron-rebuild 包重建模块以适配 Electron。这个包可以自动识别当前 Electron 版本,为你的应用自动完成下载 headers、重新编译原生模块等步骤。
"scripts": {
"rebuild": "electron-rebuild"
}
执行以下命令完成串口编译
npm run rebuild
注意:
- 编译过的串口不同系统不可通用,需在各平台重新编译
- windows系统最好是正版,或净化版。否正很有可能安装失败。