27

我正在开发一个命令行节点模块,并希望能够通过网站上的链接启动它。

我想注册一个自定义协议my-module://,使链接具有以下格式:my-module://action:some-action单击它们将启动节点包。

如果没有用于此的节点 API(我确定不会有),那么有没有办法可以通过调用系统命令从节点执行此操作?

它必须在 Windows、Linux 和 MacOS 上运行。

4

4 回答 4

28

这是一个有趣的想法。我认为目前没有跨平台的 node.js 解决方案。我确实遇到过有人要求同样的事情:

https://github.com/rogerwang/node-webkit/issues/951

Electron 现在通过macOS 和 Windows的app.setAsDefaultProtocolClientAPI(从 v0.37.4 开始)支持它。

编写库来做到这一点并不难。

窗户

在 Windows 端,您必须将应用程序注册为处理该 URI 方案的应用程序。

您需要为您的应用程序设置一个注册表项:

HKEY_CLASSES_ROOT
   警报
      (默认)=“URL:警报协议”
      URL 协议 = ""
      默认图标
         (默认) = "alert.exe,1"
      贝壳
         打开
            命令
               (默认)= "C:\Program Files\Alert\alert.exe" "%1"

然后,当您的应用程序由 windows 运行时,您应该能够看到process.argv[]. 确保你启动一个 shell 来运行节点,而不仅仅是你的应用程序。

原始 MSDN 文章

请注意,这需要管理员权限并在系统范围内设置处理程序。要为每个用户执行此操作,您可以使用HKEY_CURRENT_USER\Software\Classes代替,因为 Electron 的实现是这样做的。

苹果:

github评论中引用的“OS X”文章实际上是针对iOS的。我将查看以下编程指南,了解有关注册应用程序以处理 URL 方案的信息:

苹果开发文档

总之,您需要创建一个启动服务并使用 填充 .plist 文件CFBundleURLTypes,该字段是一个数组,应该只填充协议名称,即http

以下超级用户问题有更好的解决方案,但是是每个用户的设置。

“您要查找的文件是 ~/Library/Preferences/com.apple.LaunchServices.plist。

它包含一个名为 LSHandlers 的数组,定义 LSHandlerURLScheme 的 Dictionary 子项可以使用 LSHandlerRole 进行相应的修改。”

Linux:

据我所知,在 Linux 中有几种方法可以实现这一点(惊喜?)

Gnome 有一个工具可以让你注册一个 url 处理程序w3 档案

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

一些较轻的管理器看起来允许您创建虚假的 mime 类型并将它们注册为 URI 协议处理程序。

“为具有以下各种方案的 URI 创建假 mime-types:application/x-xdg-protocol- 支持特定 URI 协议的应用程序可以将假 mime-type 添加到其桌面条目文件中的 MimeType 键中。因此很容易找到通过在 mimeinfo.cache 文件中查找支持 URI 方案的系统上安装的所有应用程序。同样,defaults.list 文件可用于为指定的 URI 类型指定默认程序。wiki.lxde.org

KDE 也支持他们自己的处理 URL 协议处理程序的方法:

创建一个文件: $KDEDIR/share/services/your.protocol并用相关数据填充它:

[协议]
执行=/路径/到/播放器“%u”
协议=lastfm
输入=无
输出=无
助手=真
列表=
读数=假
写作=假
makedir=false
删除=假

来自各地的last.fm论坛

希望有帮助。

于 2013-11-04T15:40:59.600 回答
4

以下是我在 Mac OS 上使用应用程序 NW.js 所做的事情:

  1. 打开应用程序/Applications/Utilities/Script Editor

    在编辑器中输入以下代码

    on open location this_URL
       do shell script "/Applications/X.app/Contents/MacOS/x '" & this_URL & "'"
    end open location
    

    X替换为您的应用程序的名称。

    将脚本保存为任何位置的应用程序包

  2. 转到脚本,右键单击然后“显示包内容”然后编辑Contents/info.plist

    在文件末尾添加这些行,就在之前</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>
    
  3. 您现在可以打开以myurlscheme:开头的链接,然后查看您的应用正在打开!

于 2015-08-15T00:55:26.363 回答
2

编辑 :

看起来模块已经改变了注册过程:

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');
});

原答案:

为此目的有一个 npm 模块。

链接:https ://www.npmjs.com/package/protocol-registry

因此,要在 nodejs 中执行此操作,您只需要运行以下代码:

首先安装它

npm i protocol-registry

然后使用下面的代码注册你的入口文件。

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');
});

然后假设有人打开 testproto://test 然后将启动一个新终端执行:

node yourapp/index.js testproto://test
于 2021-04-23T14:36:01.923 回答
-27

首先创建自己的协议很疯狂,不要那样做。

似乎您想要做的就是能够从网络浏览器启动您的节点包。从 Web 浏览器启动外部程序的常规方法是编写浏览器插件。

这就是从您的浏览器启动 pdf、torrent、iTunes 的方式。

因此,总而言之,要做你想做的事,你必须编写一个插件并让你的用户安装。我会说这不是一个好主意。

于 2013-08-30T14:14:08.943 回答