2
头图

In the last issue, we introduced how to set up a pseudo-protocol and pull up the client through the pseudo-protocol link. In fact, there are many scenarios for pseudo-protocols, such as Baidu Netdisk or Thunder, click on the link on the web page to download, or click on the link to start After the client opens a certain page, in fact, this can be achieved using pseudo-protocol links. The parameters in the link are no different from the parameters of the web page. This issue will introduce how to obtain the parameters in the pseudo-protocol link.

Goals

  1. When the software is closed, the software is pulled up through the pseudo-protocol to obtain the pseudo-protocol link.
  2. When the software is started, the software is pulled up 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, and download the picture to load and display locally.

Fake agreement to get the difference

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

  1. Windows writes the pseudo protocol through the registry, calls the application startup exe and %1 start the client.
  2. The Mac starts the client info.plist file setting in the software package.

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 the pseudo protocol:

Windows pseudo protocol start processing

  1. First, if the software is closed, we open the pseudo-protocol link on the browser, find the corresponding pseudo-protocol on the registry, start the exe and pass in the pseudo-protocol link ( %1 ), that is, what we actually open is xxx.exe vue-cli-electron://xxxx ,
    At this point, you can get the pseudo-protocol link process.argv process.argv is an array, which contains the startup parameters of Electron. If we start the software through the pseudo-protocol, the last item of the array is our pseudo-protocol link.
process.argv:
[
  xxx.exe,
  .....,
  vue-cli-electron://xxxx
]

Then the pseudo protocol at this time is process.argv[process.argv.length - 1]

  1. If the software is in the open state, we can get this argv second-instance second-instance when the second instance is executed and app.requestSingleInstanceLock() is called. Explain that our software is running. The pseudo protocol triggers to open the exe. app.requestSingleInstanceLock() is called in the process, second-instance will be triggered, which is intuitively expressed as the pseudo-protocol opens the software and triggers the second-instance event. We can get argv in this.
import { app } from 'electron'
import global from '../config/global'
const gotTheLock = app.requestSingleInstanceLock()

export default function() {
  // 点击图标启动时检测窗口是否存在,存在则打开
  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 to start the Mac software, so process.argv useless, so how to get it, see the official description link :

On macOS, when a user tries to open a second instance of your application in the Finder, the system will automatically force a single instance by emitting open-file and open-url events. But 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 ensure single instance.

Therefore, we can 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)
})

Implementation

winSingle

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

export default function() {
  // 点击图标启动时检测窗口是否存在,存在则打开
  if (!gotTheLock) {
    app.quit()
  } else {
    // 这里是软件在启动时,伪协议打开触发的
    app.on('second-instance', (event, argv) => {
      console.log(argv)
      const win = global.sharedObject.win
      // 直接把伪协议链接发送给渲染进程
      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')
  }
  // 这里怎么处理看个人喜好,你可以启动时就根据scheme打开对应的窗口,或者是在窗口加载完成后发个通知给渲染进程,渲染进程进行重定向。
  // if (process.argv.length > (app.isPackaged ? 1 : 2)) {
  //   const scheme = process.argv[process.argv.length - 1]
  //   处理scheme省略
  //   initWindow('#xxxpath')
  // } else {
  //   initWindow('')
  // }
  initWindow('')
  // 这里的逻辑是win关闭通过伪协议拉起软件,由于我们要通知渲染进程,所以得在渲染进程加载完毕后通知
  win.webContents.once('did-finish-load', () => {
    // 直接打开软件的话开发环境的启动参数为2,安装包为1,大于这个数的话说明是通过伪协议拉起软件的
    if (process.argv.length > (app.isPackaged ? 1 : 2)) {
      // 我们这里主动触发'second-instance',传入process.argv,在那边统一处理了
      app.emit('second-instance', null, process.argv)
    }
  })
}
// mac伪协议链接就是urlStr
app.on('open-url', (_event, urlStr) => {
  console.log(urlStr)
  if (win) {
    // 这里是mac软件打开时使用伪协议打开软件
    win.webContents.send('renderer-scheme', urlStr)
    if (win.isMinimized()) win.restore()
    if (win.isVisible()) {
      win.focus()
    } else {
      win.show()
      win.setSkipTaskbar(false)
    }
  } else {
    // 这里是mac软件关闭时使用伪协议打开软件,如果你中间process.argv没有改变可以这样写,会继续走上面win的did-finish-load的流程
    // 如果有改变的话老老实实写个did-finish-load进行win.webContents.send('renderer-scheme', urlStr)推送
    process.argv.push(urlStr)
  }
})

Here I am when the main process obtains the pseudo-protocol link and then sends a notification to the rendering process. For some things you don’t understand, please read the comments above. To put it simply:

  • open-url with Mac pseudo-protocol in 060e85d7329b5d, and distinguish whether the software is on or off according to the value of win.
  • In ready , the software that got the pseudo-protocol is in the closed state, and the software in second-instance is in the active state.
  • If the Mac software is started in the closed state, there is only the startup path in argv, and the logic of argv.length> 1 will not be followed, but open-url will be triggered before ready. We can manually perform argv.push( Pseudo-protocol link) Let it follow the logic of Win software shutdown and startup.

Rendering process processing

The pseudo-protocol link we used here is vue-cli-electron:///file/localFile?image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg , and the complete link is also obtained. Let's deal with this link, jump to /file/localFile , and download the image image address in the query parameter. Download and display logic Use the previous load the local file logic.

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
    }
  }
})

vue-cli-electron:///file/localFile?image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg try to open 060e85d7329cd6 with a browser to see if it jumps to the route of the local file after pulling up the software, and it shows the image of the image in the pseudo protocol.

This series of updates can only be organized during weekends and after get off work hours. If there are more content, the update will be slower. I hope it can be helpful to you. Please support it by star or like favorites.

The address of this article: https://xuxin123.com/electron/url-scheme-query

This github address: link


陌路凡歌
7.9k 声望259 粉丝

人笨,多听,多写,多看书