I am developing a command line node module and would like to be able to launch it via links on a website.
I want to register a custom protocol my-module://
such that links would have the following format: my-module://action:some-action
and clicking on them would start the node package.
If there isn't a node API for this (I'm sure there won't be) then is there a way I can do it from node by invoking system commands?
It must work on Windows, Linux, and MacOS.
Its an interesting idea. I don't think there is currently a cross platform node.js solution out there. I did come across this thread of people asking for the same thing:
https://github.com/rogerwang/node-webkit/issues/951
Electron now supports it with the app.setAsDefaultProtocolClient
API ( since v0.37.4 ) for macOS and Windows.
It wouldn't be terribly difficult to write the library to do this.
::
On the windows side you'd have to register the app as the application that handles that URI scheme.
You'll need to set up a registry entry for your application:
HKEY_CLASSES_ROOT alert (Default) = "URL:Alert Protocol" URL Protocol = "" DefaultIcon (Default) = "alert.exe,1" shell open command (Default) = "C:\Program Files\Alert\alert.exe" "%1"
Then, when your application is run by windows, you should be able to see the arguments in process.argv[]
. Make sure that you launch a shell to run node, not just your application directly.
Note this requires administrator privileges and sets the handler system-wide. To do it per user, you can use HKEY_CURRENT_USER\\Software\\Classes
instead, as the Electron's implementation does it .
The cited "OS X" article in the github comment is actually for iOS. I'd look at the following programming guide for info on registering an application to handle a URL scheme:
In summary, you'll need to create a launch service and populate the .plist file with CFBundleURLTypes
, this field is an array and should be populated with just the protocol name ie http
The following Super User Question has a better solution, but is a per user setting.
"The file you seek is ~/Library/Preferences/com.apple.LaunchServices.plist.
It holds an array called LSHandlers, and the Dictionary children that define an LSHandlerURLScheme can be modified accordingly with the LSHandlerRole."
From what I can tell, there are several ways to accomplish this in Linux (surprise?)
Gnome has a tool that will let you register a url handler w3 archives
gconftool-2 -t string -s /desktop/gnome/url-handlers/tel/command "bin/vonage-call %s"
gconftool-2 -s /desktop/gnome/url-handlers/tel/needs_terminal false -t bool
gconftool-2 -t bool -s /desktop/gnome/url-handlers/tel/enabled true
Some of the lighter weight managers look like they allow you to create fake mime types and register them as URI Protocol handlers.
"Fake mime-types are created for URIs with various scheme like this: application/x-xdg-protocol- Applications supporting specific URI protocol can add the fake mime-type to their MimeType key in their desktop entry files. So it's easy to find out all applications installed on the system supporting a URI scheme by looking in mimeinfo.cache file. Again defaults.list file can be used to specify a default program for speficied URI type." wiki.lxde.org
KDE also supports their own method of handling URL Protocol Handlers:
Create a file: $KDEDIR/share/services/your.protocol
and populate it with relevant data:
[Protocol] exec=/path/to/player "%u" protocol=lastfm input=none output=none helper=true listing= reading=false writing=false makedir=false deleting=false
from last.fm forums of all places
Hope that helps.
Here's how I did on Mac OS with an application NW.js :
Open the app /Applications/Utilities/Script Editor
type the following code in the editor
on open location this_URL do shell script "/Applications/X.app/Contents/MacOS/x '" & this_URL & "'" end open location
Replace X by the name of your App.
Save the script as an Application Bundle anywhere
Go to the script, right click then ' Show Package Contents ' then edit Contents/info.plist
Add these lines at the end of the file, just before </dict></plist>
:
<key>CFBundleIdentifier</key> <string>com.mycompany.AppleScript.AppName</string> <!-- edit here --> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>AppName</string> <!-- edit here --> <key>CFBundleURLSchemes</key> <array> <string>myurlscheme</string> <!-- your url scheme here --> </array> </dict> </array>
You can now open a link starting with myurlscheme: and see your app is opening!
Looks like the module has changed the registration process for good:
const path = require('path');
const ProtocolRegistry = require('protocol-registry');
console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
protocol: 'testproto', // sets protocol for your command , testproto://**
command: `node ${path.join(__dirname, './tester.js')} $_URL_`, // this will be executed with a extra argument %url from which it was initiated
override: true, // Use this with caution as it will destroy all previous Registrations on this protocol
terminal: true, // Use this to run your command inside a terminal
script: false
}).then(async () => {
console.log('Successfully registered');
});
There is an npm module for this purpose.
link : https://www.npmjs.com/package/protocol-registry
So to do this in nodejs you just need to run the code below:
First Install it
npm i protocol-registry
Then use the code below to register you entry file.
const path = require('path');
const ProtocolRegistry = require('protocol-registry');
console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
protocol: 'testproto', // set your app for testproto://**
command: `node ${path.join(__dirname, './index.js')}`, // this will be executed with a extra argument %url from which it was initiated
}).then(async () => {
console.log('Successfully registered');
});
Then suppose someone opens testproto://test then a new terminal will be launched executing :
node yourapp/index.js testproto://test
First of all creating your own protocol is crazy, don't do that.
It seems all you want to do is to be able to launch you node package from a web-browser. The normal way to launch a external program from a web-browser is to write a browser plugin.
This is how pdf, torrents, iTunes get launched from your browser.
So in summary to do what you want you will have to write a plugin and get your users to install. Not particualy a good idea I would say.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.