Code Monkey home page Code Monkey logo

node-default-application-protocol's Introduction

node-default-application-protocol

A cross-platform, Node tool for setting, checking, and removing a custom URI protocol handler on an OS.

Example: myapp://settings could be tied to open a specific executable and pass in the argument settings (available to process.argv[]).


STATUS:

Currenlty this project is in the "planning and accepting PRs" phase.

An alternative library that has popped up after this was created may be a more valuable option:


Current status

  • Potential solution found
  • API designed (subject to change)
  • API validation
  • Windows Working
  • Linux Working
  • OSX Working
  • Published to npm

API Design (WIP)

This is just a simple draft which may change as development advances on each OS.

const protocolHandler = require('node-default-application-protocol');

// returns boolean where true = success
const protocolSet = protocolHandler.setAsDefault({
  protocol: 'myapp',
  executable: process.execPath
});

if (protocolSet) {
  console.log('Everything worked');
} else {
  console.log('There was a problem setting the protocol');
}
const protocolHandler = require('node-default-application-protocol');

// returns true if the default for a protocol matches your executable
const isProtocol = protocolHandler.isDefault({
  protocol: 'myapp',
  executable: process.execPath
});

if (isProtocol) {
  console.log('Yes, that protocol already exists');
} else {
  console.log('No it has not been set');
}
const protocolHandler = require('node-default-application-protocol');

// returns boolean where true = success
const removedProtocol = protocolHandler.removeDefault({
  protocol: 'myapp',
  executable: process.execPath
});

if (removedProtocol) {
  console.log('Removed successfully');
} else {
  console.log('There was a problem removing the protocol');
}
const protocolHandler = require('node-default-application-protocol');

// returns string of the default application for the specified protocol or undefined
const defaultApplication = protocolHandler.checkDefault({
  protocol: 'myapp'
});

if (defaultApplication) {
  console.log('The default application is', defaultApplication);
} else {
  console.log('No default application is applied to this protocol');
}

Global

These properties can be passed in to any of the methods listed below.

Key Type Allowed Default Description
verbose Boolean true, false true If true, consoles out helpful warnings and errors.
customLogger Function Any function None You can pass in your own custom function to log errors/warnings to. When called the function will receive a message string for the first argument and sometimes an error object for the second argument. This is useful in NW.js to see the messages logged to the regular Chromium Developer Tools instead of the background page's developer tools. But this can also be useful in other scenarios, like adding in custom wrappers or colors in a command line/terminal. This function may be called multiple times before all synchronous tasks complete.

require('node-default-application-protocol').setAsDefault()

NOT IMPLEMENTED

Returns boolean. true = worked. false = didn't work.

Key Type Allowed Default Description
protocol String Any URL safe string This is a required field This is the custom protocol you are defining.
executable String Any valid path to a file process.execPath The executable called when the custom protocol is called

require('node-default-application-protocol').isDefault()

NOT IMPLEMENTED

Returns boolean. true = is set as default. false = is not set as default.

Key Type Allowed Default Description
protocol String Any URL safe string This is a required field This is the custom protocol you are checking.
executable String Any valid path to a file process.execPath The executable called when the custom protocol is called

require('node-default-application-protocol').removeDefault()

NOT IMPLEMENTED

Returns boolean. true = worked. false = didn't work.

Key Type Allowed Default Description
protocol String Any URL safe string This is a required field This is the custom protocol you are removing.
executable String Any valid path to a file process.execPath The executable called when the custom protocol was called

require('node-default-application-protocol').checkDefault()

NOT IMPLEMENTED

Returns string of the application set as the default for the passed in protocol. String format may differ depending on platform.

Key Type Allowed Default Description
protocol String Any URL safe string This is a required field This is the custom protocol you are checking.

The solution comes from:

It links to other resources which have already faded from the internet, so for safety I will duplicate its contents here below.




Problem

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.

Solution

It's 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:

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.

Windows:

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.

OSX:

The cited "OSX" 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 i.e. 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."

Linux:

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.

Solution courtesy of: jeremy

Discussion




Related Resources:

node-default-application-protocol's People

Contributors

thejaredwilcurt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

node-default-application-protocol's Issues

Which RegEdit library to use

The current set of libraries for interacting with the registry have some limitations:

  • windows-registry
    • ๐Ÿคท Depends on ffi at runtime, which may cause issues with webpack-ing.
    • ๐Ÿ˜ƒ Has a decent sized API. It could be simplified a little more, but most of the hard work is done.
    • ๐Ÿ˜” Requires Visual Studio 2015, Visual C++ Build Tools or Visual Studio 2017. Also requires Python 2.7. Also requires node-gyp. Node version must match version in NW.js.
      • I think the only way around this would be to call reg.exe directly, which could conflict with Group Policy rules.
    • ๐Ÿ˜ Written in JS and has tests in place
    • ๐Ÿ˜ž Doesn't seem to be merging in PRs any more.
    • ๐Ÿ˜ž Doesn't seem to be compatible with Node 12+ (according to PR's, have not tested yet)
  • native-reg
    • ๐Ÿคฎ Written in TerperScrips and C++
    • ๐Ÿคท Uses NAPI for a Node "in process native module", not sure what the pros/cons of this are
    • ๐Ÿ˜จ Seems to try to be a one-for-one wrapper around the Windows Registry API, which is pretty nasty looking, and thus the library's API, though not as bad, is still pretty gnarly.
    • ๐Ÿ˜ Maintainer has said he is willing to take help on designing a better API
    • ๐Ÿคฎ "Documentation" requires reading the source code (TS ๐Ÿคฎ) and comparing against Microsoft's documentation (๐Ÿคฎ).
    • ๐Ÿ‘ This may be the most complete option though
    • ๐Ÿ˜Œ Maintainer seems helpful.
  • node-winreg
    • ๐Ÿ˜• Depends on reg.exe which breaks as soon as you enable "Prevent access to registry editing tools" Group Policy rules (including QUERY operations). More details.
  • registry-js
    • ๐Ÿคท Supposedly faster than reg.exe, though who cares?
    • ๐Ÿ˜’ Literally only has 1 item in the API (to read a list). Which requires a lot of boilerplating to handle response.
    • ๐Ÿ˜’ Cannot create or destroy keys.
    • ๐Ÿ˜’ Maintainers are not working on it but "will review PRs".
    • ๐Ÿคฎ Code is written in C++ and TerperScrips (why call this registrty-js then?)
    • ๐Ÿ˜ฉ Requires custom build for Electron, so may not be easily compatible with NW.js.
    • ๐Ÿ˜ก Was built by GitHub Desktop team, which may have bias against NW.js (as seen by previous GitHub developers refusing to make minor code changes in projects to support both Electron and NW.js. GitHub is ironically the worst at open source. Similar to Facebook's approach of "build it for us, you can use it too, but we won't merge your PR's if they don't benefit us, make your own library").
    • ๐Ÿ˜” Requires Visual Studio 2015, Visual C++ Build Tools or Visual Studio 2017. Also requires Python 2.7. Also requires node-gyp. Node version must match version in NW.js.
  • Write my own custom approach using something like invoking PowerShell.
    • ๐Ÿคท This would be slow, but I don't really care about performance.
    • ๐Ÿ˜ข Would become its own project which may take even longer to build than this one
    • ๐Ÿ˜ช Would require a lot more research and more intimate knowledge of the registry and how to interact with it.
    • ๐Ÿ˜จ Ultimately may have similar group policy restrictions, would be difficult and painful to test for this if there isn't clear documented guidance around this online.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.