Windows - Electron 使用协议(带参数)在当前活动的电子应用程序中“做某事”

Raf*_*fty 3 javascript electron

更新如下

注意:此应用程序仅适用于 Windows,因此排除了“open-url”等。

我的协议适用于我的应用程序,它成功打开了电子应用程序,但是我正在寻找的是,如果应用程序打开并且用户单击带有参数的协议链接( my-app://go/to/ this/section )它将打开当前应用程序并运行一个函数来转到链接。

目前实际发生的情况是应用程序打开其自身的另一个版本并且不传递参数。

我的 app.js 中有一个setAsDefaultProtocolClient函数可以尝试捕获协议的任何实例,但这似乎不起作用。

const {remote} = window.require('electron');    
remote.app.setAsDefaultProtocolClient( 'my-app' );
Run Code Online (Sandbox Code Playgroud)

我的主进程中还具有makeSingleInstance仅允许应用程序的一个实例同时运行的功能,但是在关闭第二个客户端时,它似乎没有发送我通过协议传递的参数。

// Make sure there is only 1 instance of the app running at a time
const isSecondInstance = app.makeSingleInstance((commandLine, workingDirectory) => {
    if (mainWindow) {
        if (mainWindow.isMinimized()) mainWindow.restore();
        mainWindow.focus();
    }
});
// If this is a second instance of the app close it
if (isSecondInstance) {
    app.quit();
}
Run Code Online (Sandbox Code Playgroud)

更新:

我现在已经有第二个窗口将其协议发布到应用程序的原始实例,但是我无法记录参数。

每当我登录process.argv并使用“my-app://section/29”时,它只是安装目录的目录,没有任何参数。

我已将以下内容添加到makeSingleInstance

if (process.platform == 'win32') {
    deeplinkingUrl = process;
    // Keep only command line / deep linked arguments
    logEverywhere( process );
}
Run Code Online (Sandbox Code Playgroud)

这里logEverywhere仅供参考:

function logEverywhere(s) {
    console.log(s);
    if (mainWindow && mainWindow.webContents) {
        mainWindow.webContents.executeJavaScript(`console.log("${s}")`);
    }
}
Run Code Online (Sandbox Code Playgroud)

Tre*_*vor 5

Electron 的新版本改变了它的工作方式。makeSingleInstance已弃用。requestSingleInstanceLock代替使用。这是一个样本。

import { app, ipcMain as ipc } from 'electron'
import { find, compact } from 'lodash'
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
  app.quit()
} else {
  app.on('second-instance', (event, commandLine, workingDirectory) => {
    // Someone tried to run a second instance, we should focus our window.
    // mainWindow is window created with `new BrowserWindow(params)`
    if (mainWindow) {
      // And use ipc, or promiseIpc to send the command line 
      // to the renderer to handle it however we want
      const cmd = find(commandLine, cmd => {
        return cmd.indexOf('app-protocol-name') > -1
      })
      let actualCommands = cmd.replace('app-protocol-name://', '')
      actualCommands = compact(actualCommands.split('/'))
      ipc.send('NEW_COMMAND_LINE', mainWindow, actualCommands)
      mainWindow.show()
      mainWindow.restore()
      mainWindow.focus()
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

commandLine有时会是一个包含 10 个或更多元素的数组。因此,您必须在其中搜索实际包含协议的元素。然后对参数进行适当的拆分和处理。这段代码不会处理诸如正斜杠或引号之类的事情。但它是一个开始