Introduction


electron is developed by Github , is an open source library with Html, css, JavaScript to build desktop applications , can be packaged for Mac, Windows, Linux system under the application .


electron is a runtime environment, including Node and Chromium, can be understood as the web application running in the node environment

structure


electron is mainly divided into the main process and the rendering process, the relationship is as follows


The process in which electron runs the script identified in the main field of package.json is called the master process.


Create web pages in the master process to display user pages, an electron has one and only one master process.


electron uses Chromium to display web pages, each running in its own 

 Quick Start


Next, let the code speak for itself, the thundering hello world


Create a folder and run npm init -y to generate the package.json file, download the electron module and add the development dependencies

mkdir electron_hello && cd electron_hello && npm init -y && npm i electron -D


The download speed is too slow or failed, please try to use cnpm, the installation method is as follows

# cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# electron
cnpm i electron -D

  Create index.js, and write the following

const {app, BrowserWindow} = require('electron')


let win

function createWindow () {      win = new BrowserWindow({ width: 800, height: 600 })
    

    win.loadFile('./index.html')
    

    win.webContents.openDevTools()
    

    
    win.on('closed', () => {
        win = null 
    })
}


app.on('ready', createWindow)  


app.on('window-all-closed', () => {

   if (process.platform !== 'darwin') {
        app.quit()
   }
})
  
app.on('activate', () => {

    if (win === null) {
      createWindow()
    }
})

  Create index.html

<!DOCTYPE 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>


Finally, modify the main field in packge.json and add the start command.

{
    ...
    main:'index.js',
    scripts:{
        "start": "electron ."
    }
}


After executing npm run start , our application will pop up.

debug


We know electron has two processes, the main process and the rendering process, how do we need to debug them during development? The old lady eats persimmons, let’s pick the soft one!

 rendering process


BrowserWindow is used to create and control the browser window, and we call the API on its instance.

win = new BrowserWindow({width: 800, height: 600})
win.webContents.openDevTools() 


The debugging is the same as Chrome.

main process

 Debugging with VSCode

 Open the project using VSCode and click the debug button

 Click on the drop-down box after debugging

 Select Add Configuration and choose node

 This turns on the default debugging configuration, which looks like this


What? Yours isn’t, and if it isn’t, just copy and replace the following with your configuration


That’s pretty much it, so copy the second item from configurations into your configurations configuration, the first one is for debugging node

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "",
      "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" : ["."]
      }
  ]
}


You can see ${workspaceFolder} , which is a variable about VSCode, used to indicate the path of the currently opened folder

 After modifying the configuration, let’s debug the panel and select what we just configured


Mark the places in the code that need to be debugged and click on the little green triangles for a happy debugging session!

 process communication


In Electron, GUI-related modules (such as dialog, menu, etc.) are only available in the main process, not in the rendering process. In order to use them in the rendering process, the ipc module is necessary to send inter-process messages to the main process.

Hello, brothers


ipcMain and ipcRenderer are two good friends, through these two modules can realize the process communication.


  • ipcMain is used in the main process to handle synchronous and asynchronous messages sent by the rendering process (web page)


  • The ipcRenderer is used in the rendering process to send synchronous or asynchronous messages to the main process, and can also be used to receive reply messages from the main process.


The communication between the above two modules can be understood as ,Next, we look at their specific use of methods

main process

const {ipcMain} = require('electron')


ipcMain.on('something', (event, data) => {
    event.sender.send('something1', '')
})

 rendering process

const { ipcRenderer} = require('electron') 


ipcRenderer.send('something', '')  


ipcRenderer.on('something1', (event, data) => {
    console.log(data) 
})


The above code uses asynchronous transfer messages. electron also provides an API for synchronous transfer.


Sending a synchronization message will block the entire rendering process, and you should avoid using this approach – unless you know what you’re doing.


Never use ipc to pass large amounts of data, there will be major performance issues that can seriously get your whole app stuck.


With the remote module, you can call methods of the main process object without having to explicitly send interprocess messages.

const { dialog } = require('electron').remote
dialog.showMessageBox({type: 'info', message: ''})


webContents, which is responsible for rendering and controlling the web page, is a property of the BrowserWindow object, and we use the send method to send asynchronous messages to the renderer process.

main process

const {app, BrowserWindow} = require('electron')

let win

app.on('ready', () => {

    win = new BrowserWindow({width: 800, height: 600})
    
   
    win.loadURL('./index.html')
    
   
    win.webContents.on('did-finish-load', () => {

       
        win.webContents.send('something', 'data')
    })
})

 rendering process

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <script>
            require('electron').ipcRenderer.on('something', (event, message) => {
                console.log(message) 
            })
        </script>
    </body>
</html>

  Rendering process data sharing


More often than not, we use HTML5 API implementations such as localStorage, sessionStorage, etc., which can also be implemented using electron’s IPC mechanism

main process

global.sharedObject = {
    someProperty: 'default value'
}

 rendering process

 first page

require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'

  Second page

console.log(require('electron').remote.getGlobal('sharedObject').someProperty) // new value

Summarize


All of the above four methods can realize the communication between the main process and the rendering process, you can find that using the remote module is the simplest, and the rendering process can use the electron module directly in its code.

 Common Modules

 Shortcuts and menus

 Local Shortcuts

 It is only triggered when the application is focused, the main code is as follows

 The official documentation is not working.

const { Menu, MenuItem } = require('electron')
const menu = new Menu()
  
menu.append(new MenuItem({
  label: '',
  submenu: [
    {
      label: '',
      accelerator: 'CmdOrCtrl+P',
      click: () => { 

      }
    }
  ]
}))
Menu.setApplicationMenu(menu)

  Global Shortcuts


Registers the global, which is triggered regardless of whether the app is focused or not, using globalShortcut to do so, with the following main code, the

const {globalShortcut, dialog} = require('electron')

app.on('read', () => {
    globalShortcut.register('CmdOrCtrl+1', () => {
        dialog.showMessageBox({
            type: 'info',
            message: ''
          })
    })
})

 The following is displayed, using the dialog module

 context menu (computing)


The context menu is the menu that appears when we right-click, and is set inside the rendering process.

 The main code is as follows

const remote = require('electron').remote;  
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);

  application menu (computing)


Above we created a local shortcut through the Menu module, the application menu is also using the Menu module, we see that it looks like the same, in fact, the implementation is similar, we use the creation of templates here to achieve the main code is as follows:

const {app, Menu} = require('electron')
const template = [
  {
    label: 'action',
    submenu: [{
        label: 'copy',
        accelerator: 'CmdOrCtrl+C',
        role: 'copy'
    }, {
        label: 'paset',
        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: 'reload',
    submenu: [
      {
        label: 'youtube',
        accelerator: 'CmdOrCtrl+P',
        click: () => { console.log('time to print stuff') }
      },
      {
        type: 'separator'
      },
      {
        label: 'google',
      }
    ]
  }
]

if (process.platform === 'darwin') {
    const name = electron.app.getName()
    template.unshift({
      label: name,
      submenu: [{
        label: `about ${name}`,
        role: 'about'
      }, {
        type: 'separator'
      }, {
        label: 'services',
        role: 'services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        label: `  ${name}`,
        accelerator: 'Command+H',
        role: 'hide'
      }, {
        label: 'hide other',
        accelerator: 'Command+Alt+H',
        role: 'hideothers'
      }, {
        label: 'more',
        role: 'unhide'
      }, {
        type: 'separator'
      }, {
        label: 'esc',
        accelerator: 'Command+Q',
        click: function () {
          app.quit()
        }
      }]
    })
}

app.on('read', () => {
    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
})

  system tray

 Primary Code

const { app, Tray } = require('electron') 

let tray;
app.on('ready', () => {
    tray = new Tray(__dirname + '/build/icon.png');
    
    const contextMenu = Menu.buildFromTemplate([
      {label: 'show', type: 'radio', click: () => {win.show()}},
      {label: 'hidden', type: 'radio', click: () => {win.hide()}},
    ])
    
    // tray.on('click', () => { 
    //   win.isVisible() ? win.hide() : win.show()
    // })
    
    tray.setToolTip('This is my application.') 
    
    tray.setContextMenu(contextMenu) 
})

 

 Open page

shell


When the main process opens a page, it calls the default browser to open the page, using the shell module

const { app,shell } = require('electron')

app.on('ready', () => {
    shell.openExternal('github.com')
})


Once the app is launched it opens the github page using the default browser

window.open

 Used during the rendering process, the current application opens the page

window.open('github.com')

webview


Use webview to display external web content in a separate frame and process.

 Just use it directly in index.html

<webview id="foo" src="https://www.github.com/" style="display:inline-flex; width:640px; height:480px"></webview>

stencil

electron-forge


Electron-forge includes out-of-the-box templates for vue , react , Angular and more.

npm i -g electron-forge
electron-forge init my-app template=react
cd my-app
npm run start 

  The directory structure is as follows


.compilerc It is the configuration file of electron-compile , similar to .babelrc .


electron-compile is a conversion rule that supports compiling js and css in an application.

electron-react-boilerplate


If you don’t want any tools and want to simply start building from a template, react-electron template can be understood.


electron-react-boilerplate is a dual package.json configuration project with the following directory

electron-vue


electron-vue makes full use of vue-cli as a scaffolding tool, along with webpack, electron-packager, or electron-builder with vue-loader, and some of the most commonly used plugins, such as vue-router, vuex, and so on.

 The directory structure is as follows

 More templates

 For more templates, please visit

Pack


How to package our developed application into .app or .exe executable, this involves the important part of packaging, here use electron-quick-start project for packaging


Currently, there are two main packaging tools electron-packager and electron-builder.


Mac package window installer need to download the wine

brew install wine

 If there are missing components, just follow the error message to download them

electron-packager


electron-packager packages your electron into a runnable file (.app, .exe, etc)

 Execute npm i electron-packager -D to install

  electron-packager . Quick Pack

 Packaging Details

electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> --out=out --icon=assets/app.ico --asar --overwrite --ignore=.git

  • sourcedir project entry directory according to package.json
  •  appname Package name

  • platform Build the platform to include darwin, linux, mas, win32 all
  •  arch Build Architecture Contains ia32,x64,armv7l,arm64
  •  out Packed address
  •  icon Packaging icon

  • asar Whether to generate app.asar, otherwise it’s your own source code.
  •  overwrite overwrites the last package
  •  ignore Files that are not packaged


The first time the package needs to download the binary package will take a little longer, later go to the cache is much faster.

 The packaged directory is

 where electron-quick-start can be opened and run directly

 cache address

  • Mac~/Library/Caches/electron/
  • Windows $LOCALAPPDATA/electron/Cacheor~/AppData/Local/electron/Cache/
  • Linux $XDG_CACHE_HOMEor~/.cache/electron/

electron-builder


electron-builder is a complete solution for macos, windows, linux electron app, it can provide packaging and building related functions. It also provides out-of-the-box support for “automatic updates”.

  npm i electron-builder -D downloading

  electron-builder ask for a doggy bag (at a restaurant)

 The following appears


Again, it will take a little longer to pack for the first time, so don’t fret and wait for the good news.

 It will be packaged by default in the dist directory, containing the following


mac The file has  is packaged by default using the asar method

  electron-builder --dir Only generates package files, useful for testing

pit pit pit


The first time to pack will be slower, if you and I hand and directly quit, and again when packing, congratulations, an error. The error message is as follows

  • electron-builder version=20.28.2
  • loaded configuration file=package.json ("build" field)
  • description is missed in the package.json appPackageFile=/Users/shisan/Documents/self/you-app/package.json
  • writing effective config file=dist/builder-effective-config.yaml
  • no native production dependencies
  • packaging       platform=darwin arch=x64 electron=2.0.7 appOutDir=dist/mac
  • cannot unpack electron zip file, will be re-downloaded error=zip: not a valid zip file
  ⨯ zip: not a valid zip file

Error: /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:21
    at 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: `electron-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 interface


The problem is that when downloading the .zip package, the operation is interrupted, and all future executions of the package, can not find the file (or the mutilated file) will report an error, you need to manually clear the cache Cache path in the ~/Library/Caches/electron/

 Common Parameters


electron-builder The configuration file is written in the build field in package.json

"build": {
    "appId": "com.example.app", 
    "productName": "测试",
    "directories": {
        "buildResources": "build", 
        "output": "dist" 
    },
    "mac": {
        "category": "public.app-category.developer-tools", 
        "target": ["dmg", "zip"],  
        "icon": "build/icon.icns" 
    },
    "dmg": {
        "background": "build/background.tiff or build/background.png", 
        "title": "标题",
        "icon": "build/icon.icns"
    },
    "win": {
        "target": ["nsis","zip"] 
    }
}


Use electron-package or electron-builder for packaging, there is no need for asar to package manually, these two tools are already integrated, the following content just to do to understand the

asar

Introduction


asar is a tar-like archive format that combines multiple files into a single file. Electron can read the contents of any file from it without having to decompress the entire file.

use


Above we see that when we use electron-package for packaging, we can add --asar parameter, its function is to package our source code into asar format, if not used, it is our source code.


Still using the electron-quick-start template, packaged using electron-package

 Select the application in the packaged directory and right-click 

 Open the paths in turn Contents -> Resources -> app

 And you can see our original file.


Use electron-package . --asar for packaging, and check again to see that the source files in the app have been packaged into a asar file

 Common commands

  • Pack
asar pack|p <dir> <ouput>

 as if asar ./ app.asar

  • Unzip
asar extract|e <archive> <output>

 as if asar e app.asar ./


In fact, even with asar packaging, our source code is still exposed, and can still be easily decrypted using asar decompression. Using webpack to compress and obfuscate the code is the way to go.

 automatic update


We use electron-builder and electron-updater to do automatic updates to the application, not electron’s autoUpdater

process

 Creating Certificates


Regardless of the method used for automatic updates, code signing is essential, and we tested automatic updates by creating a local certificate

 Find Keychain Access in Other

 


Make a strong name, choose for the certificate type, and click on Create

 Find it in your keychain when you’re done creating it


Right-click and select Change Trust Settings to set the trust to 

 code signature

  •  No code signature

  •  code signature

 Setting environment variables

 Execute sudo vi ~/.bash_profile , add variables

export CSC_NAME="electron_update"

 Execute source ~/.bash_profile to reload the variables file


Execute echo $CSC_NAME to see if the variable has taken effect, if not, execute the above command to reload the file.


If you still can’t get the variable after reloading several times, just exit the terminal and log in again.

 Packing Code


Packaged using electron-builder , the project uses electron-quick-start


We’ll start by adding the packaged build configuration, and in package.json add the

"build": {
    "appId": "org.electron.com",
    "publish": [
      {
        "provider": "generic",
        "url": "http://172.28.86.36:8080/" 
      }
    ],
    "productName": "231",
    "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"
        }
      ]
    }
}


Earlier, we talked about the meaning of each parameter in the build field, so we won’t go into it here. Here we have added the publish field, which configures our auto-update information, and the url is the server address.


For servers we can use the http-server module to quickly set up a static server.

 After executing the package, the output

 Look mainly at the latest-mac.yml file


You can see the version field, which is used to indicate the current version of the application, so where does this field come from?


That’s right it’s the version field in our package.json file

 automatic update

 Write the following code in the master process

const {app, BrowserWindow, ipcMain} = require('electron')

const { autoUpdater } = require('electron-updater')


const feedURL = `http://172.28.82.40:8080/`

let mainWindow

function createWindow () {
  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()
  }
})

ipcMain.on('update', (e, arg) => {
  checkForUpdate()
})

const checkForUpdate = () => {

  autoUpdater.setFeedURL(feedURL)


  autoUpdater.on('error', message => {
    sendUpdateMessage('err', message)
  })

  autoUpdater.on('checking-for-update', message => {
    sendUpdateMessage('checking-for-update', message);
  })
 // 
  autoUpdater.on('download-progress', function(progressObj) {
    sendUpdateMessage('downloadProgress', progressObj);
  });

  autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
      
      ipcMain.on('updateNow', (e, arg) => {
          autoUpdater.quitAndInstall();
      });
      sendUpdateMessage('isUpdateNow');
  });

  autoUpdater.checkForUpdates();
}

function sendUpdateMessage(message, data) {
  mainWindow.webContents.send('message', { message, data });
}

  Then change the code of our rendering process

const {ipcRenderer} = require ('electron');
const button = document.querySelector('#button')


const ul = document.querySelector('ul')
button.onclick = () => {
  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('?')) {
        ipcRenderer.send('updateNow');
    }
  }
})

  page code


  Here the button click event is used to trigger the update operation.

 Just pack it up and install this 1.0.3 version.


Then change the version field in the file at package.json to 1.0.5 and change the index.html one to 1.0.5 to package it.

 Create a folder somewhere random like test


Move the packaged files to test and execute http-server ./ to build the service


When we click on the button, we can update the application as follows


After clicking ok and waiting for a few moments, the latest version of the app was opened after the update

 The above completes the automatic update of electron.

By lzz

Leave a Reply

Your email address will not be published. Required fields are marked *