如何从网站启动我的电子应用程序

Posted

技术标签:

【中文标题】如何从网站启动我的电子应用程序【英文标题】:How to launch my electron app from a website 【发布时间】:2019-05-01 00:38:30 【问题描述】:

我们有一个电子加密应用程序可以签署交易(除其他外)。

我们希望其他网站能够有一个按钮来打开该电子应用程序,并预先填充一些参数(交易信息)。

流程是:

    用户在 some-crypto-site.com 上点击“进行交易” electron 应用程序打开并带有预填充的参数 用户在电子应用中点击“签署交易” electron 应用在幕后做事 electron 应用程序关闭并向 some-crypto-site.com 发送消息

这可以在运行时或安装时完成。

我尝试了什么(linux、chrome)

用this gist的代码调用app.setAsDefaultProtocolClient,基本上就是:

app.setAsDefaultProtocolClient("my-app")

但是在我将my-app://foo?bar=baz 放入 chrome 浏览器后,我得到以下弹出窗口,并且按 open-xdg 什么都不做(除了关闭弹出窗口)

我看过

    Electron protocol api 似乎只处理应用内协议 webtorrent .desktop file这可能是要走的路,我只是不知道该怎么做。

也许有办法在安装时通过electron builder 这样做?

提前感谢您的帮助,我不知道如何在此处继续!

可能有用的资源

    github repo with mac+window example github comment for linux github comment for linux 2 SO answer for all 3 OSs SO windows answer npm package for windows registery SO mac answer SO linux answer microsoft docs for windows windows article github comment for windows github comment for mac info.plst for mac old repo for mac and win

【问题讨论】:

调用app.setAsDefaultProtocolClient("my-app"),然后用my-app://foo?bar=baz打开它,结果调用"your/path/electron.exe my-app://foo?bar=baz"。 delectron.exe 会将其第一个参数作为应用程序路径,因此它不起作用。 @hiitiger 感谢您的评论,我不明白您在说什么。你能澄清一下吗? 您好,我不确定您是否真的可以从 chrome 中打开 Electron 应用程序,但如果它已经打开,您可以向它发送内容。可以吗? 【参考方案1】:

因为这可能与我在工作中所做的事情有关,所以我决定试一试。 不过我只在 OSX 上测试过!

我查看了app.setAsDefaultProtocolClient 的文档,上面写着:

注意:在 macOS 上,您只能注册已添加到应用程序 info.plist 中的协议,不能在运行时修改。但是,您可以在构建期间使用简单的文本编辑器或脚本更改文件。有关详细信息,请参阅 Apple 的文档。

可以在使用electron-builder 打包您的应用程序时定义这些协议。见build


  "name": "foobar",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": 
    "start": "electron .",
    "dist": "electron-builder"
  ,
  "devDependencies": 
    "electron": "^3.0.7",
    "electron-builder": "^20.38.2"
  ,
  "dependencies": ,
  "build": 
    "appId": "foobar.id",
    "mac": 
      "category": "foo.bar.category"
    ,
    "protocols": 
      "name": "foobar-protocol",
      "schemes": [
        "foobar"
      ]
    
  

在你的主线程中:

const app, BrowserWindow = require('electron');

let mainWindow;

function createWindow () 
  mainWindow = new BrowserWindow(width: 800, height: 600)
  mainWindow.loadFile('index.html');


app.on('ready', createWindow);

var link;

// This will catch clicks on links such as <a href="foobar://abc=1">open in foobar</a>
app.on('open-url', function (event, data) 
  event.preventDefault();
  link = data;
);

app.setAsDefaultProtocolClient('foobar');

// Export so you can access it from the renderer thread
module.exports.getLink = () => link;

在您的渲染器线程中:

注意使用remote API 来访问主线程中导出的getLink 函数

<!DOCTYPE html>
<html>
  <body>
    <p>Received this data <input id="data"/></p>
    <script>
      const getLink = require('electron').remote.require('./main.js');
      document.querySelector('#data').value = getLink();
    </script>
  </body>
</html>

示例

<a href="foobar://abc=1">open in foobar</a>

这也允许您从命令行启动:

open "foobar://xyz=1"

你如何回到原来的来电者那里?

我想当您启动应用程序时,您可以包含调用方 url:

<a href="foobar://abc=1&caller=example.com”>open in foobar</a>

当您的电子应用完成数据处理后,它会简单地 ping 回该网址

学分

我的大部分发现基于:

从此GitHub issue 还有来自@oikonomopo 的excellent work

【讨论】:

太棒了,会尽快调查的!这对您的开发有用吗,或者您是否必须制作一个安装程序并安装它才能在您的本地机器上进行这项工作?再次感谢! 其实我没试过。这确实针对打包和安装的应用程序进行了测试。 在 linux 上,我尝试过使用压缩打包的应用程序,但它不起作用。目前我们没有使用 linux 的安装程序,所以无法测试。如果我们让它工作,我们会更新。 请注意,open-url 事件仅适用于 mac。 Windows 和 Linux 需要使用 process.argv 的 argv 参数来循环访问这些参数并检查其中之一是否是用于启动应用程序的 url。【参考方案2】:

与上面的有点不同。

open-url 在 ready 事件之前触发,因此您可以将其存储在变量中并在寡妇 did-finish-load 中使用。

let link;

let mainWindow;

function createWindow() 
    mainWindow = new BrowserWindow(
        width: 1280,
        height: 720,
        webPreferences: 
            nodeIntegration: true,
            contextIsolation: false
        
    );
    mainWindow.openDevTools();
    mainWindow.setContentProtection(true);
    mainWindow.loadFile('index.html');
    mainWindow.webContents.on("did-finish-load", function() 
        mainWindow.webContents.send('link', link);
    );


app.on('ready', createWindow);

// This will catch clicks on links such as <a href="protocols://abc=1">open in foobar</a>
app.on('open-url', function(event, url) 
    link = url;
    if (mainWindow?.webContents) 
        mainWindow.webContents.send('link', link);
    
);

app.setAsDefaultProtocolClient('protocols');

然后您可以像这样在渲染 html 中使用该值。

<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <script>
            const ipc = require("electron").ipcRenderer;
            ipc.on("link", function (event, url) 
                console.log(url);
                console.log(parseQuery(decodeURI(url)));
            );
            function parseQuery(queryString) 
                queryString = queryString.substring(queryString.indexOf("://") + 3);
                var query = ;
                var pairs = (queryString[0] === "?" ? queryString.substr(1) : queryString).split("&");
                for (var i = 0; i < pairs.length; i++) 
                    var pair = pairs[i].split("=");
                    query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
                
                return query;
            
        </script>
    </body>
</html>

【讨论】:

我在 Windows 中尝试了上述步骤,向我抛出一个错误,指出无法找到电子应用程序.. 有什么建议吗?

以上是关于如何从网站启动我的电子应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何从 mac 上的 node.js 脚本启动电子应用程序?

从链接或电子邮件启动 Android 应用程序

如何从网站启动安卓应用

我的WordPress网站已关闭,如何重新启动它?

如何从 iOS 应用程序启动 Safari 并打开 URL

如何在我的网站上使用卖家电子邮件地址而不是客户端ID