preface
This article contains packaging, automatic update, simple API, debugging, process communication and other related knowledge points, the content is more, may cause discomfort, please check (manual funny).
electron
Introduction to the
Developed by Github, Electron is an open source library that builds desktop applications using Html, CSS, and JavaScript, and can be packaged for Mac, Windows, and Linux operating systems.
Electron is a runtime environment containing Node and Chromium, which can be interpreted as running a Web application in Node
structure
Electron is mainly divided into the main process and the rendering process, as shown in the following figure
Electron running the main field in package.json indicates that the script process is called the main process
Create a Web page in the main process to display the user page. A ELECTRON has and only one main process
Electron uses Chromium to present Web pages, each page running in its own rendering process
Quick start
Next, let the code do the talking, the untouchable Hello World
Create a folder and execute NPM init -y to generate package.json file, download the Electron module and add development dependencies
mkdir electron_hello && cd electron_hello && npm init -y && npm i electron -D
Copy the code
If the download speed is too slow or fails, use CNPM. The installation method is as follows
# download CNPM
npm install -g cnpm --registry=https://registry.npm.taobao.org
# download electron
cnpm i electron -D
Copy the code
Create index.js and write the following
const {app, BrowserWindow} = require('electron')
// Create global variables and reference them below to avoid GC
let win
function createWindow () {
// Create a browser window and set the width and height
win = new BrowserWindow({ width: 800.height: 600 })
// Load the page
win.loadFile('./index.html')
// Open the developer tool
win.webContents.openDevTools()
// Add the window closing event
win.on('closed', () => {
win = null // Cancel the reference})}// Call the function after initialization
app.on('ready', createWindow)
Exit when all Windows are closed.
app.on('window-all-closed', () = > {// On macOS, unless the user explicitly exits with Cmd + Q,
// Otherwise, most apps and their menu bar remain active.
if(process.platform ! = ='darwin') {
app.quit()
}
})
app.on('activate', () = > {// On macOS, when you click the Dock icon and no other Windows open,
// Usually a window is recreated in the application.
if (win === null) {
createWindow()
}
})
Copy the code
Create index. HTML
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1 id="h1">Hello World!</h1>
We are using node
<script>
document.write(process.versions.node)
</script>
Chrome
<script>
document.write(process.versions.chrome)
</script>,
and Electron
<script>
document.write(process.versions.electron)
</script>
</body>
</html>
Copy the code
Finally, modify the main field in packge.json and add the start command
{... main:'index.js'.scripts: {"start": "electron ."}}Copy the code
After executing NPM run start, our application will pop up.
debugging
We know that Electron has two processes, the main process and the renderer process. How do we debug them during development? The old lady eats persimmon, let’s pick the soft one
Rendering process
BrowserWindow is used to create and control the BrowserWindow by calling the API on its instance
win = new BrowserWindow({width: 800.height: 600})
win.webContents.openDevTools() // Enable debugging
Copy the code
Debugging up and Chrome is the same, do not want to be so sour cool
The main process
Use VSCode for debugging
Open the project with VSCode and click the debug button
Click the debug drop-down box
Select Add Configuration, select Node
The default debug configuration is turned on, which looks something like this
What? Yours is not, if not, just copy the following and replace your configuration
Configurations. If you want to do that, copy the second item in configurations into your Configurations. The first configuration is used to debug node
{
"version": "0.2.0"."configurations": [{"type": "node"."request": "launch"."name": "Start program"."program": "${workspaceFolder}/main.js"
},
{
"name": "Debug Main Process"."type": "node"."request": "launch"."cwd": "${workspaceFolder}"."runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron"."windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args" : ["."]]}}Copy the code
You can see ${workspaceFolder}, which is a variable about VSCode that represents the path of the currently open folder
Please click here for more variables
After modifying the configuration, we debug the panel and select what we just configured
Mark where you need to debug in your code, and then click on the green triangle
Process of communication
In Electron, GUI-related modules (dialog, Menu, etc.) are only available in the main process, not in the renderer process. In order to use them in the renderer process, the IPC module is required to send interprocess messages to the main process. The following describes several methods of interprocess communication.
Elder brother good
IpcMain and ipcRenderer are two good gay friends, through these two modules can realize the process of communication.
-
IpcMain is used in the main process to process synchronous and asynchronous information sent by the renderer process (web page)
-
IpcRenderer is used in the renderer process to send synchronous or asynchronous messages to the main process, and can also be used to receive replies from the main process.
The communication of the above two modules can be understood as publish-subscribe mode. Next, let’s see how they are used
The main process
const {ipcMain} = require('electron')
// Listen for events from the renderer
ipcMain.on('something', (event, data) => {
event.sender.send('something1'.'I'm the value returned by the main process')})Copy the code
Rendering process
const { ipcRenderer} = require('electron')
// Send events to the main process
ipcRenderer.send('something'.'Value transferred to main process')
// Listen for events from the main process
ipcRenderer.on('something1', (event, data) => {
console.log(data) // I am the value returned by the main process
})
Copy the code
The above code uses asynchronous transmission of messages. Electron also provides an API for synchronous transmission.
Sending synchronous messages will block the entire rendering process and you should avoid using this method – unless you know what you are doing.
Don’t use IPC to transfer large amounts of data. It can cause performance problems and even make your entire application get stuck.
Remote module
With the remote module, you can call methods on the main process object without having to explicitly send interprocess messages.
const { dialog } = require('electron').remote
dialog.showMessageBox({type: 'info'.message: 'Module that uses the main process directly in the renderer process'})
Copy the code
webContents
WebContents, which renders and controls the web page, is a property of the BrowserWindow object, and we use the Send method to send an asynchronous message to the renderer process.
The main process
const {app, BrowserWindow} = require('electron')
let win
app.on('ready', () => {
win = new BrowserWindow({width: 800.height: 600})
// Load the page
win.loadURL('./index.html')
// Triggered when navigation is complete, i.e. the TAB's spinner will stop spinning and assign the onload event.
win.webContents.on('did-finish-load', () = > {// Send data to the renderer
win.webContents.send('something'.'Data sent by the main process to the renderer')})})Copy the code
Rendering process
<html>
<head>
</head>
<body>
<script>
require('electron').ipcRenderer.on('something', (event, message) => {
console.log(message) // The data that the main process sends to the renderer
})
</script>
</body>
</html>
Copy the code
Renderer data sharing
In more cases, we use HTML5 API implementation, such as localStorage, sessionStorage, etc., and can also use ELECTRON IPC mechanism to implement
The main process
global.sharedObject = {
someProperty: 'default value'
}
Copy the code
Rendering process
First page
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
Copy the code
Second page
console.log(require('electron').remote.getGlobal('sharedObject').someProperty) // new value
Copy the code
conclusion
The above four methods can realize the communication between the main process and the renderer process. It can be found that using the remote module is the simplest, and the renderer process code can directly use the ELECTRON module
Commonly used modules
Shortcut keys and menus
Local shortcut keys
Only triggered when focusing is applied, the main code is as follows
Official documentation has no effect on the test
const { Menu, MenuItem } = require('electron')
const menu = new Menu()
menu.append(new MenuItem({
label: 'Custom shortcut keys'.submenu: [{label: 'test'.accelerator: 'CmdOrCtrl+P'.click: (a)= > {
console.log('I'm a local shortcut')
}
}
]
}))
Menu.setApplicationMenu(menu)
Copy the code
Global shortcut key
Global registration, regardless of whether the application is focused or not, is triggered. Use globalShortcut to register with the main code as follows,
const {globalShortcut, dialog} = require('electron')
app.on('read', () => {
globalShortcut.register('CmdOrCtrl+1', () => {
dialog.showMessageBox({
type: 'info'.message: 'You pressed the global register shortcut.'})})})Copy the code
The dialog module is used as shown below
Context menu
The context menu is the menu that is displayed when we right-click, and is set in the renderer process
The main code is as follows
const remote = require('electron').remote; // A module that can only be used by the main program through the remote module
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
var menu = new Menu();
menu.append(new MenuItem({ label: 'MenuItem1'.click: function() { console.log('item 1 clicked'); }})); menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: 'MenuItem2'.type: 'checkbox'.checked: true }));
window.addEventListener('contextmenu', (e) => {
e.preventDefault();
menu.popup(remote.getCurrentWindow());
}, false);
Copy the code
The application menu
Above we created a local shortcut key through the Menu module, the application Menu is also used by the Menu module, we see that looks like the same, in fact, the implementation is similar, we use here to create a template to achieve, the main code is as follows:
const {app, Menu} = require('electron')
const template = [
{
label: 'operation'.submenu: [{
label: 'copy'.accelerator: 'CmdOrCtrl+C'.role: 'copy'
}, {
label: 'paste'.accelerator: 'CmdOrCtrl+V'.role: 'paste'
}, {
label: 'reload'.accelerator: 'CmdOrCtrl+R'.click: function (item, focusedWindow) {
if (focusedWindow) {
// on reload, start fresh and close any old
// open secondary windows
if (focusedWindow.id === 1) {
BrowserWindow.getAllWindows().forEach(function (win) {
if (win.id > 1) {
win.close()
}
})
}
focusedWindow.reload()
}
}
}]
},
{
label: 'Load web page'.submenu: [{label: 'youku'.accelerator: 'CmdOrCtrl+P'.click: (a)= > { console.log('time to print stuff')}}, {type: 'separator'
},
{
label: "Baidu",}]}]if (process.platform === 'darwin') {
const name = electron.app.getName()
template.unshift({
label: name,
submenu: [{
label: ` about${name}`.role: 'about'
}, {
type: 'separator'
}, {
label: 'service'.role: 'services'.submenu: []}, {type: 'separator'
}, {
label: Hidden `${name}`.accelerator: 'Command+H'.role: 'hide'
}, {
label: 'Hide the other'.accelerator: 'Command+Alt+H'.role: 'hideothers'
}, {
label: 'Show all'.role: 'unhide'
}, {
type: 'separator'
}, {
label: 'exit'.accelerator: 'Command+Q'.click: function () {
app.quit()
}
}]
})
}
app.on('read', () = > {const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
})
Copy the code
The system tray
The main code
const { app, Tray } = require('electron')
/* omit other code */
let tray;
app.on('ready', () => {
tray = new Tray(__dirname + '/build/icon.png');// System tray icon
const contextMenu = Menu.buildFromTemplate([ / / the menu item
{label: 'show'.type: 'radio'.click: (a)= > {win.show()}},
{label: 'hide'.type: 'radio'.click: (a)= > {win.hide()}},
])
// Tray. on('click', () => {// The mouse click event is best set with only one menu
// win.isVisible() ? win.hide() : win.show()
// })
tray.setToolTip('This is my application.') // Mouse over the prompt
tray.setContextMenu(contextMenu) // Apply the menu item
})
Copy the code
The module”
Menu
MenuItem
globalShortcut
dialog
tray
Open the page
shell
The main process opens the page and invokes the default browser to open the page, using the shell module
const { app,shell } = require('electron')
app.on('ready', () => {
shell.openExternal('github.com')})Copy the code
The github page will be opened using the default browser once the app is launched
window.open
Used in the rendering process, the current application opens the page
window.open('github.com')
Copy the code
webview
Use webView to display external Web content in a separate frame and process
Use it directly in index.html
<webview id="foo" src="https://www.github.com/" style="display:inline-flex; width:640px; height:480px"></webview>
Copy the code
The module”
shell
window.open
webview
QA
Other application modules and apis can be downloaded
Demo application
Demo application Chinese version
template
electron-forge
Electron forge contains templates for vue, React, Angular, and more out of the box.
npm i -g electron-forge
electron-forge init my-app template=react
cd my-app
npm run start
Copy the code
The directory structure is as follows
.compilerc is the configuration file for electron-compile, similar to.babelrc
Electron -compile is a conversion rule that allows you to compile JS and CSS in your application
electron-react-boilerplate
If you don’t want any tools and want to simply build from a template, the React-electron template can take a look.
Electron -react- Boilerplate is a double package.json configuration project with the following directory
electron-vue
Electric-vue makes full use of vue-CLI as a scaffolding tool, plus webpack, electric-Packager, or electric-Builder with vue-Loader, and some of the most commonly used plug-ins, For example, vuE-Router and VUex.
The directory structure is as follows
Chinese tutorial
More templates
More templates are available here
packaging
How do we package our developed application as an.app or.exe executable file, and that involves an important part of packaging, which is using the electron quick-start project
At present, the mainstream packaging tools have two electric-packager and electric-Builder
You need to download Wine to pack the Windows installation package for Mac
brew install wine
If any component is missing, download it according to the error message
electron-packager
Electron packager packs your electron into runnable files (.app,.exe, etc)
Run the NPM I electron-packager -d command to install the package
Electron -packager. Quick pack
Packaging,
electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> --out=out --icon=assets/app.ico --asar --overwrite --ignore=.git
Copy the code
- Sourcedir Project entry directory according to package.json
- Appname package name
- Platform Construction Platform includes
darwin, linux, mas, win32 all
- The ARCH build architecture contains
ia32,x64,armv7l,arm64
- Out The address after packing
- Icon Package icon
- Asar generates app.asar, or its own source code
- Overwrite overwrites the last package
- Ignore files that are not packaged
The first time you pack a package that requires a binary download will take a little longer, and the cache will be much faster later.
The package directory is
The electron-quick-start can be directly opened and run
Cache address
- Mac
~/Library/Caches/electron/
- Windows
$LOCALAPPDATA/electron/Cache
or~/AppData/Local/electron/Cache/
- Linux
$XDG_CACHE_HOME
or~/.cache/electron/
electron-builder
Electron Builder is a complete solution to pack and build the Electron App for MacOS, Windows and Linux. It also provides “automatic update” support out of the box
NPM I electron- Builder-d download
Electron – builder package
In the following
Also, it will take a long time to pack for the first time. Don’t worry, wait for good news.
Will be packaged in the dist directory by default, including the following
MAC files have runtime files that are packaged using ASAR by default
The electron-builder –dir will only generate package files, useful for testing
Pit craters
The first time when packing will be slow, if you and I hand out directly, when packing again, congratulations, mistake. The error message is as follows
• electron - builder version =20.282.
• loaded configuration file=package.json ("build"Field • Description is missedin the package.json appPackageFile=/Users/Shisan/Documents/self/you - app/package. The json, writing effective config file = dist/builder - effective - config. Yaml, no Native production Dependencies • Packaging platform= Darwin arch= X64 electron=2.07.AppOutDir = Dist/MAC • Cannot unpack the electron zip file, will be re-downloaded error=zip: not a valid zip file ⨯ zip: not a valid zip fileError: /Users/shisan/Documents/self/you-app/node_modules/app-builder-bin/mac/app-builder exited with code 1
at ChildProcess.childProcess.once.code (/Users/shisan/Documents/self/you-app/node_modules/builder-util/src/util.ts:254:14)
at Object.onceWrapper (events.js:272:13)
at ChildProcess.emit (events.js:180:13)
at maybeClose (internal/child_process.js:936:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
From previous event:
at unpack (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/out/electron/ElectronFramework.js:191:18)
at Object.prepareApplicationStageDirectory (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/electron/ElectronFramework.ts:148:50)
at /Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/platformPackager.ts:179:21at Generator.next (<anonymous>) From previous event: at MacPackager.doPack (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/platformPackager.ts:166:165) at /Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/macPackager.ts:88:63 at Generator.next (<anonymous>) From previous event: at MacPackager.pack (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/macPackager.ts:80:95) at /Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:376:24 at Generator.next (<anonymous>) at xfs.stat (/Users/shisan/Documents/self/you-app/node_modules/fs-extra-p/node_modules/fs-extra/lib/mkdirs/mkdirs.js:56:16) at /Users/shisan/Documents/self/you-app/node_modules/graceful-fs/polyfills.js:287:18 at FSReqWrap.oncomplete (fs.js:171:5) From previous event: at Packager.doBuild (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:344:39) at /Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:314:57 at Generator.next (<anonymous>) at /Users/shisan/Documents/self/you-app/node_modules/graceful-fs/graceful-fs.js:99:16 at /Users/shisan/Documents/self/you-app/node_modules/graceful-fs/graceful-fs.js:43:10 at FSReqWrap.oncomplete (fs.js:153:20) From previous event: at Packager._build (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:285:133) at /Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:281:23 at Generator.next (<anonymous>) From previous event: at Packager.build (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/packager.ts:238:14) at build (/Users/shisan/Documents/self/you-app/node_modules/app-builder-lib/src/index.ts:58:28) at build (/Users/shisan/Documents/self/you-app/node_modules/electron-builder/src/builder.ts:227:10) at then (/Users/shisan/Documents/self/you-app/node_modules/electron-builder/src/cli/cli.ts:42:48) at runCallback (timers.js:763:18) at tryOnImmediate (timers.js:734:5) at processImmediate (timers.js:716:5) From previous event: at Object.args [as handler] (/Users/shisan/Documents/self/you-app/node_modules/electron-builder/src/cli/cli.ts:42:48) at Object.runCommand (/Users/shisan/Documents/self/you-app/node_modules/yargs/lib/command.js:237:44) at Object.parseArgs [as _parseArgs] (/Users/shisan/Documents/self/you-app/node_modules/yargs/yargs.js:1085:24) at Object.get [as argv] (/Users/shisan/Documents/self/you-app/node_modules/yargs/yargs.js:1000:21) at Object.<anonymous> (/Users/shisan/Documents/self/you-app/node_modules/electron-builder/src/cli/cli.ts:25:28) at Module._compile (internal/modules/cjs/loader.js:654:30) at Object.Module._extensions.. js (internal/modules/cjs/loader.js:665:10) at Module.load (internal/modules/cjs/loader.js:566:32) at tryModuleLoad (internal/modules/cjs/loader.js:506:12) at Function.Module._load (internal/modules/cjs/loader.js:498:3) at Function.Module.runMain (internal/modules/cjs/loader.js:695:10) at startup (internal/bootstrap/node.js:201:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] dist: 'electric-Builder -- MAC -- X64' NPM ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] dist script.npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/shisan/.npm/_logs/ 2018-08-22t06_28_55_102z-debug. Log * Error building interactive interfaceCopy the code
The problem is in the download. Zip, interrupted operation, all performed after packaging, can’t find the file (or incomplete documents) is an error, need to clear the cache manually Cache path in ~ / Library/Caches/electron /
Commonly used parameters
The electron builder configuration file is written in the Build field in package.json
Directories: {"build": {"appId": "com.example.app", // App directories: {"buildResources": "Build ", // Build resource path defaults to build" output": "dist" // Output directory defaults to dist}," MAC ": {"category": "Public. App-category. Developer-tools ", // Application category "target": [" DMG ", "zip"], // Target package type "icon": "Build /icon.icns" // icon path}," DMG ": {"background": "Build /background.tiff or build/background. PNG ", // background image path "title": "title", "icon": "build/icon.icns" // icon path}, "win": {"target": ["nsis","zip"] // Target type}}Copy the code
Application category
More parameters
There is no need for ASAR manual packaging by using the electric-package or electric-Builder. These two tools have been integrated into the package. The following content is just for understanding
asar
Introduction to the
Asar is a tar-like archive format that combines multiple files into a single file. Electron can read any file contents from it without decompressing the entire file.
use
As we have seen above, we can add the — ASar parameter when using electron package. This parameter is used to package our source code into ASAR format, otherwise it will be our source code.
The electron-quick-start template is still used, and the electron-package is used for packaging
After the package is packaged, right-click the application directory to display the package content
Go to Contents -> Resources -> app
You can see our original file
Use the electron-package. –asar to pack and check again that the source files in your app have been packed as ASAR files
Common commands
- packaging
asar pack|p <dir> <ouput>
Copy the code
Such as asar. / app. Asar
- Unpack the
asar extract|e <archive> <output>
Copy the code
Such as asar e app.asar./
In fact, even with asAR packaging, our source code is still exposed, can be easily decrypted with ASAR decompression, and is king with WebPack to compress and obturate the code.
Automatic updates
We use electron builder and electron updater to automatically update our applications, not the autoUpdater in Electron
process
Create a certificate
Regardless of which method is used for automatic updates, code signing is essential, and we used to create a local certificate to test automatic updates
Find keystring access in others
Choose Keychain Access -> Certificate Assistant -> Create Certificate to create a new certificate
Give a loud name, select code signature for the certificate type, and click Create
Find it in the keychain after it is created
Right-click and select Change Trust Settings to set trust to always trust
Code signing
-
No code signature
-
Code signing
Setting environment Variables
Run sudo vi ~/.bash_profile to add variables
export CSC_NAME="electron_update"
Copy the code
Run source ~/.bash_profile to reload the variable file
Run echo $CSC_NAME to check whether the variable takes effect. If it does not, run the preceding command to reload the file
If the variable is still unavailable after multiple reloading, exit the terminal directly and log in to the terminal again
Packaging code
Use electric-Builder for packaging and electric-quick-start for projects
Let’s start by adding the packaged build configuration in package.json
"build": { "appId": "org.electron.com", "publish": [ { "provider": "generic", "url": "Http://172.28.86.36:8080/"}], "productName" : "my", "directories" : {" output ":" dist "}, "MAC" : {" target ": [ "dmg", "zip" ] }, "win": { "target": [ "nsis", "zip" ] }, "dmg": { "backgroundColor": "red", "title": "made", "contents": [ { "x": 400, "y": 128, "type": "link", "path": "/Applications" } ] } }Copy the code
In the build field, we added the Publish field, which is configured to update automatically, and the URL is the server address.
The server is available to ushttp-serverModule, quickly build a static server
After performing packaging, output
Take a look at the latest-mac.yml file
You can see the Version field, which indicates the current version of the application. Where did this field come from?
That’s the version field in our package.json file
Automatic updates
Write the following code in the main process
const {app, BrowserWindow, ipcMain} = require('electron')
const { autoUpdater } = require('electron-updater')
// Address of the local server
const feedURL = ` http://172.28.82.40:8080/ `
let mainWindow
function createWindow () { // Create window
mainWindow = new BrowserWindow({width: 800.height: 600})
mainWindow.loadFile('index.html')
mainWindow.on('closed'.function () {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed'.function () {
if(process.platform ! = ='darwin') {
app.quit()
}
})
app.on('activate'.function () {
if (mainWindow === null) {
createWindow()
}
})
// Listen for custom update events
ipcMain.on('update', (e, arg) => {
checkForUpdate()
})
const checkForUpdate = (a)= > {
// Set the url to check for updates and initiate automatic updates
autoUpdater.setFeedURL(feedURL)
// Listening error
autoUpdater.on('error', message => {
sendUpdateMessage('err', message)
})
// Triggered when checking for updates
autoUpdater.on('checking-for-update', message => {
sendUpdateMessage('checking-for-update', message);
})
//
autoUpdater.on('download-progress'.function(progressObj) {
sendUpdateMessage('downloadProgress', progressObj);
});
// Update the download completion event
autoUpdater.on('update-downloaded'.function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
ipcMain.on('updateNow', (e, arg) => {
autoUpdater.quitAndInstall();
});
sendUpdateMessage('isUpdateNow');
});
// Check with the server to see if any updates are available now
autoUpdater.checkForUpdates();
}
// Sending a message triggers the message event
function sendUpdateMessage(message, data) {
mainWindow.webContents.send('message', { message, data });
}
Copy the code
Then change our renderer code
const {ipcRenderer} = require ('electron');
const button = document.querySelector('#button')
const ul = document.querySelector('ul')
button.onclick = (a)= > {
ipcRenderer.send('update')
}
ipcRenderer.on('message', (event, {message,data }) => {
let li = document.createElement('li')
li.innerHTML = message + " <br>data:" + JSON.stringify(data) +"<hr>";
ul.appendChild(li)
if (message === 'isUpdateNow') {
if (confirm('Update now? ')) {
ipcRenderer.send('updateNow'); }}})Copy the code
Page code
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<h1>The current version is 1.0.3</h1>
<ul>
<li>Life cycle process display</li>
</ul>
<button id="button">Click on the I</button>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>
Copy the code
The update action is triggered by a button click event.
Package it and install the 1.0.3 version.
Then change the version field in the package.json file to 1.0.5 and the index.html field to 1.0.5 to package.
Create a folder anywhere, such as test
Move the packaged file to test and run http-server./ to set up the service
When we click the button, we can update the application, as shown below
Click OK, wait for a moment, and then open the latest version of the app
That completes the automatic update of ELECTRON.
The last
All the code in this article can be found at Github
OCR related demo borrows (Chao) from (XI) Jartto’s electron- OCR, which is linked below.
reference
Summary of common parameters of the electron-packager command
Electron package Mac installation package code signature problem solution
Uncle Sunan’s electron
electron-ocr
The signature mentioned in this article must be purchased with an Apple developer account.