Previous we introduced how to set up a pseudo protocol, and link up the client through agreement, actually pseudo agreement and there are many scenarios, such as baidu cloud or thunderbolt, click the link to download a web page, or click the link up after the client open a page, it can be implemented using pseudo agreement link, The parameters in the link are no different from the parameters in the web page. This installment introduces how to obtain the parameters in the pseudo-protocol link.

Achieve the goal

  1. When the software is closed, pull up the software through the pseudo protocol to obtain the pseudo protocol link.
  2. When the software is started, pull up the software through the pseudo protocol to obtain the pseudo protocol link.
  3. Pass a picture link and router path through the pseudo protocol, jump to the path, and download the picture to load the display locally.

Pseudo-protocol gets the difference

In the previous chapter we introduced how the pseudo protocol is used to start the client, namely:

  1. Windows is through registry write pseudo protocol, call application start EXE andThe % 1Start the client.
  2. Mac is available through software packagesinfo.plistFile Settings to start the client.

The two startup methods are different, so the acquisition method is also different, let’s look at the startup process through the pseudo protocol:

Windows pseudo protocol processing

  1. First of all, if the software is closed, we will open the pseudo-protocol link on the browser, then we will look for the corresponding pseudo-protocol in the registry, start the EXE and pass in the pseudo-protocol link (The % 1), that is, what we actually open isxxx.exe vue-cli-electron://xxxx.

Argv is an array containing the Electron startup parameter. If we pull up the software through the pseudo protocol, the last item in the array will be our pseudo protocol link

process.argv:
[
  xxx.exe,
  .....,
  vue-cli-electron://xxxx
]
Copy the code

Argv [process.argv.length-1]

  1. If the software is on, we can use the appsecond-instanceEvent to get this argv,second-instanceWhen the second instance is executed and calledapp.requestSingleInstanceLock()When triggered, the explanation is that our software is running, pseudo protocol triggered open exe, our main process calledapp.requestSingleInstanceLock()Words,second-instanceWill trigger, intuitive performance of pseudo protocol open software, triggersecond-instanceEvent, we can get argv in this.
import { app } from 'electron'
import global from '.. /config/global'
const gotTheLock = app.requestSingleInstanceLock()

export default function() {
  // Check whether the window exists when clicking the icon to start
  if(! gotTheLock) { app.quit() }else {
    app.on('second-instance'.(event, argv) = > {
      console.log(argv[argv.length - 1])
      const win = global.sharedObject.win
      if (win) {
        if (win.isMinimized()) win.restore()
        if (win.isVisible()) {
          win.focus()
        } else {
          win.show()
          win.setSkipTaskbar(false}}})}}Copy the code

Mac pseudo-protocol processing

Mac software starts with no parameters, so process.argv is useless.

On macOS, when a user tries to open a second instance of your application in the Finder, the system automatically forces a single instance by issuing open-file and open-URL events. But when the user launches the application from the command line, the system’s singleton mechanism is bypassed, and you must call this method manually to ensure singleton.

Therefore, we can obtain our pseudo-protocol link through open-URL. Note: The Mac system is obtained through open-URL regardless of whether the software is started or not

app.on('open-url'.(_event, urlStr) = > {
  console.log(urlStr)
})
Copy the code

The specific implementation

winSingle

import { app } from 'electron'
import global from '.. /config/global'
const gotTheLock = app.requestSingleInstanceLock()

export default function() {
  // Check whether the window exists when clicking the icon to start
  if(! gotTheLock) { app.quit() }else {
    // This is triggered when the pseudo protocol is opened during software startup
    app.on('second-instance'.(event, argv) = > {
      console.log(argv)
      const win = global.sharedObject.win
      // Send the pseudo-protocol link directly to the renderer
      win.webContents.send('renderer-scheme', argv[argv.length - 1])
      if (win) {
        if (win.isMinimized()) win.restore()
        if (win.isVisible()) {
          win.focus()
        } else {
          win.show()
          win.setSkipTaskbar(false}}})}}Copy the code

The main process

import winSingle from './services/winSingle'

winSingle()

app.isReady() ? onAppReady() : app.on('ready', onAppReady)

async function onAppReady() {
  if(! process.env.WEBPACK_DEV_SERVER_URL) { createProtocol('app')}// Depending on your personal preference, you can either open the corresponding window according to Scheme at startup, or send a notification to the renderer when the window is loaded and the renderer redirects it.
  // if (process.argv.length > (app.isPackaged ? {1, 2))
  // const scheme = process.argv[process.argv.length - 1]
  // Processing scheme is omitted
  // initWindow('#xxxpath')
  // } else {
  // initWindow('')
  // }
  initWindow(' ')
  // The logic here is that Win shuts down and pulls up the software through the pseudo protocol. Since we need to notify the renderer, we need to notify it after the renderer has finished loading
  win.webContents.once('did-finish-load'.() = > {
    // If you open the software directly, the startup parameter of the development environment is 2, and the installation package is 1. If the number is larger than this, it indicates that the software is pulled up through a pseudo protocol
    if (process.argv.length > (app.isPackaged ? 1 : 2)) {
      // we trigger 'second-instance' and pass it to process.argv
      app.emit('second-instance'.null, process.argv)
    }
  })
}
// MAC pseudo-protocol links are urlStr
app.on('open-url'.(_event, urlStr) = > {
  console.log(urlStr)
  if (win) {
    // Here is the MAC software open using the pseudo protocol open software
    win.webContents.send('renderer-scheme', urlStr)
    if (win.isMinimized()) win.restore()
    if (win.isVisible()) {
      win.focus()
    } else {
      win.show()
      win.setSkipTaskbar(false)}}else {
    If process.argv does not change, it will continue to follow the did-finish-load process in win
    // If there is any change, just write did-finish-load and push win.webcontents. Send ('renderer-scheme', urlStr)
    process.argv.push(urlStr)
  }
})
Copy the code

The main process receives the pseudo-protocol link and sends a notification to the renderer process. Please refer to the above comment for explanation.

  • inopen-urlIn the Mac pseudo-protocol, the software is on or off according to the value of WIN.
  • inreadyThe one with the fake protocol is the one with the software turned off,second-instanceThe software is in the startup state.
  • Argv. length > 1 will not be triggered before ready, but open-URL will be triggered before Ready. In this case, we can manually argv.push(pseudo protocol link) to make it follow Win to close the startup logic.

Render process handling

Here we use pseudo agreement to link to the vue cli – electron: / / / file/localFile? image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg, also get the full link, we deal with this link, jump to the file/localFile, And download the image address from the query parameter. Download and display logic using the previous logic to load local files.

App.vue
onMounted(() = > {
  window.ipcRenderer.on('renderer-scheme'.(_event, data) = > {
    console.log(data)
    const urlObj = new URL(data)
    const query = {}
    urlObj.search.slice(1).split('&').forEach(s= > {
      const item = s.split('=')
      query[item[0]] = item[1]
    })
    router.replace({
      path: urlObj.pathname.slice(2),
      query
    })
  })
})
onUnmounted(() = > {
  window.ipcRenderer.removeAllListeners('renderer-scheme')})Copy the code
localFile.vue
onMounted(() = > {
  const localImage = LgetItem('localImage')
  if (route.query.image) {
    download(route.query.image)
  } else {
    if (localImage) {
      state.image = localImage
    }
  }
})
Copy the code

Ok, then use the browser to open the vue – cli – electron: / / / file/localFile? image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg try, see if pull up software after the jump to a local file routing, and shows the pseudo image pictures in the agreement.

This series of updates can only be arranged during weekends and off-duty hours. If there are too many contents, the update will be slow. I hope it will be helpful to you

Address: xuxin123.com/electron/ur…

This article github address: link