问题
We have an electron crypto app that signs transactions (among other things).
We want other websites to have the ability to have a button that opens that electron app, pre-filled with some params (the transaction information).
flow is:
- user clicks "make transaction" on some-crypto-site.com
- electron app opens up with pre-filled params
- user clicks "sign transaction" in electron app
- electron app does stuff behind the scenes
- electron app closes and sends a message to some-crypto-site.com
This could be done at runtime, or install time.
What I tried (linux, chrome)
calling app.setAsDefaultProtocolClient with the code of this gist, which is basically:
app.setAsDefaultProtocolClient("my-app")
But after I put my-app://foo?bar=baz
in chrome browser, I get the following popup, and pressing open-xdg does nothing (other than dismissing the popup)
I looked into
- Electron protocol api which seems to handle in-app protocols only
- webtorrent .desktop file This might be the way to go, I'm just not sure how to go about it.
Maybe there's a way to do so at install time through electron builder?
Thanks in advance for the help, I have no idea how to proceed here!
Resources that might be useful
- 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
回答1:
Since this may be relevant to what I’m doing at work, I decided to give it a go. I’ve only tested this on OSX though!
I looked at the documentation for app.setAsDefaultProtocolClient and it says this:
Note: On macOS, you can only register protocols that have been added to your app's info.plist, which can not be modified at runtime. You can however change the file with a simple text editor or script during build time. Please refer to Apple's documentation for details.
These protocols can be defined when packaging your app with electron-builder
. See 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"
]
}
}
}
In your main thread:
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;
In your renderer thread:
Notice the use of the remote API to access the getLink
function exported in the main thread
<!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>
Example
<a href="foobar://abc=1">open in foobar</a>
This also allows you to launch from the command line:
open "foobar://xyz=1"
How do you get back to the original caller?
I suppose that when you launch the app you could include the caller url:
<a href="foobar://abc=1&caller=example.com”>open in foobar</a>
When your electron app finishes processing data, it would simply ping back that url
Credits
Most of my findings are based on:
- From this GitHub issue
- And the excellent work from @oikonomopo
来源:https://stackoverflow.com/questions/53530726/how-to-launch-my-electron-app-from-a-website