Electron pseudo protocol parameter acquisition

Time:2021-7-30

In the last issue, we introduced how to set the pseudo protocol and pull up the client through the pseudo protocol link. In fact, there are many scenarios for the pseudo protocol, such as Baidu online disk or Xunlei. Click the link on the web page to download, or click the link to pull up the client and open a page. In fact, this can be realized by using the pseudo protocol link, The parameters in the link are no different from those in the web page. This issue introduces how to obtain the parameters in the pseudo protocol link.

Achieve goals

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

Pseudo protocol acquisition difference

In the previous chapter, we introduced how the pseudo protocol starts the client, namely:

  1. Windows writes the pseudo protocol through the registry and calls the application to start exe and%1Start the of the client.
  2. Mac is through the software packageinfo.plistFile settings to start the client.

The startup methods of the two are different, so the acquisition methods are also different. Let’s take a look at the startup process through pseudo protocol:

Windows pseudo protocol startup processing

  1. First, if the software is closed, we open the pseudo protocol link in the browser, find the corresponding pseudo protocol in the registry, start exe and pass in the pseudo protocol link(%1)That is, what we actually open isxxx.exe vue-cli-electron://xxxx
    At this point, you can directlyprocess.argvTo get this pseudo protocol link, as I said beforeprocess.argvThis is the array, which contains the startup parameters of electron. If we pull up the software through the pseudo protocol, the last item in the array is our pseudo protocol link
process.argv:
[
  xxx.exe,
  .....,
  vue-cli-electron://xxxx
]

Then the pseudo protocol isprocess.argv[process.argv.length - 1]

  1. If the software is turned on, we can use the appsecond-instanceEvent to get this argv,second-instanceWhen the second instance is executed and calledapp.requestSingleInstanceLock()When triggered, it is explained that our software is running, and the pseudo protocol triggers to open the EXE, which is called in our main process.app.requestSingleInstanceLock()If so,second-instanceIt will trigger, which is intuitively expressed as pseudo protocol. Open the software and triggersecond-instanceEvent, we can get argv in this.
import { app } from 'electron'
import global from '../config/global'
const gotTheLock = app.requestSingleInstanceLock()

export default function() {
  //When clicking the icon to start, check whether the window exists. If it exists, it will be opened
  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)
        }
      }
    })
  }
}

Mac pseudo protocol processing

There are no parameters for mac software startup, soprocess.argvThis thing is useless, so how to get it? Look at the official descriptionlink

On MacOS, when a user tries to open a second instance of your application in the finder, the system automatically enforces a single instance by issuing open file and open URL events,. However, when the user starts the application on the command line, the single instance mechanism of the system will be bypassed, and you must manually call this method to confirm the instance.

So we can passopen-urlTo get our pseudo protocol link. Note: the MAC system is through whether the software is started or notopen-urlCome and get it

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

Concrete implementation

winSingle

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

export default function() {
  //When clicking the icon to start, check whether the window exists. If it exists, it will be opened
  if (!gotTheLock) {
    app.quit()
  } else {
    //This is triggered when the pseudo protocol is opened when the software is started
    app.on('second-instance', (event, argv) => {
      console.log(argv)
      const win = global.sharedObject.win
      //Send the pseudo protocol link directly to the rendering process
      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)
        }
      }
    })
  }
}

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')
  }
  //How to handle it here depends on your personal preferences. You can open the corresponding window according to the scheme at startup, or send a notification to the rendering process after the window is loaded, and the rendering process will redirect.
  // if (process.argv.length > (app.isPackaged ? 1 : 2)) {
  //   const scheme = process.argv[process.argv.length - 1]
  //Handling scheme ellipsis
  //   initWindow('#xxxpath')
  // } else {
  //   initWindow('')
  // }
  initWindow('')
  //The logic here is that win closes and pulls up the software through the pseudo protocol. Because we want to notify the rendering process, we have to notify it after the rendering process is loaded
  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 it is greater than this number, it indicates that the software is pulled up through a pseudo protocol
    if (process.argv.length > (app.isPackaged ? 1 : 2)) {
      //We actively trigger 'second instance' here and pass in process.argv, which is processed uniformly there
      app.emit('second-instance', null, process.argv)
    }
  })
}
//Mac pseudo protocol link is urlstr
app.on('open-url', (_event, urlStr) => {
  console.log(urlStr)
  if (win) {
    //Here is the pseudo protocol used to open the mac software
    win.webContents.send('renderer-scheme', urlStr)
    if (win.isMinimized()) win.restore()
    if (win.isVisible()) {
      win.focus()
    } else {
      win.show()
      win.setSkipTaskbar(false)
    }
  } else {
    //Here is the pseudo protocol used to open the software when the mac software is closed. If your intermediate process.argv does not change, you can write this. You will continue to follow the did finish load process of win
    //If there is any change, write a did finish load to push win.webcontents.send ('renderer scheme ', urlstr)
    process.argv.push(urlStr)
  }
})

Here, the main process obtains the pseudo protocol link and sends a notification to the rendering process. For some incomprehensible points, please refer to the notes above for explanation. To put it simply:

  • stayopen-urlThe pseudo protocol of MAC is processed in, and the software is turned on or off according to the value of win.
  • stayreadyThe software that gets the pseudo protocol is closed,second-instanceThe software is in the startup state.
  • If the mac software is started in the off state, there is only one startup path in argv, and the logic of argv.length > 1 will not be followed. However, the open URL will be triggered first than ready. We can manually argv.push (pseudo protocol link) in this to let it follow the logic of win software off and startup.

Rendering process processing

The pseudo protocol link we use here isvue-cli-electron:///file/localFile?image=https://imgs.developpaper.com/imgs/1.jpg, we also got the complete link. Let’s deal with this link and jump to/file/localFile, and download the image address in the query parameter. Download and display logic with previousLoad local fileThe logic of.

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')
})
localFile.vue
onMounted(() => {
  const localImage = LgetItem('localImage')
  if (route.query.image) {
    download(route.query.image)
  } else {
    if (localImage) {
      state.image = localImage
    }
  }
})

OK, then open it with the browservue-cli-electron:///file/localFile?image=https://imgs.developpaper.com/imgs/1.jpgTry to see if you jump to the route of local files after pulling up the software, and the image in the pseudo protocol is displayed.

This series of updates can only be sorted out on weekends and after work time. If there are more contents, the update will be slow. I hope it can be helpful to you. Please give more star or like collection support

Address:https://xuxin123.com/electron/url-scheme-query

GitHub address:link