【问题标题】:How to map a custom protocol to an application on the Mac?如何将自定义协议映射到 Mac 上的应用程序?
【发布时间】:2010-10-03 01:31:11
【问题描述】:

我正在尝试将自定义协议注册到 Mac 上的应用程序,即:

  1. 用户点击带有“abcdef://some/url/here”的链接
  2. 一个已安装的应用程序启动,上面的字符串作为第一个参数传递

我已经使用这个问题的信息在 Windows 上成功完成了这项工作:

how do I create my own URL protocol? (e.g. so://...)

我更愿意找到独立于浏览器的东西,换句话说,在操作系统级别。我还想通过一个 shell 脚本来自动化这个注册,所以希望有一种不涉及 GUI 的方法来做到这一点。

谢谢!

【问题讨论】:

    标签: macos protocols protocol-handler custom-url-protocol


    【解决方案1】:

    我没有机会使用它,但前段时间我收藏了OS X URL handler to open links to local files,这正是您要找的。​​p>

    链接过程的重要部分是将适当的CFBundleURLTypes 添加到描述该方案的应用程序的 Info.plist 中。那里给出的示例如下所示:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>Local File</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>local</string>
            </array>
        </dict>
    </array>
    

    【讨论】:

    • 我在任何地方都看到过这个解决方案:不过,这个协议处理程序实际上是什么时候注册的呢?用户是否必须第一次运行该应用程序?
    • 是的,您必须运行应用程序来注册处理程序,然后才能透明地使用它(假设应用程序隐藏了它的停靠图标)。
    • @iconoclast 因为 OS X 中的大多数应用程序都是通过复制安装的,所以 Info.plist 文件在复制时注册(通常到 /Appplications/Foo 文件夹)。在某些情况下,如果 mimetypes 或 URL 方案没有自动注册,reboot may be needed.
    【解决方案2】:

    在 Mac 上,使用 AppleScript 很容易做到这一点。最详细的描述在这篇文章中,Launch Scripts from Webpage Links on Mac。我会阅读该页面,因为它包含完整的演练和完整的工作示例供下载。

    基本上,您可以在脚本中创建一个事件处理程序:

    on open location this_URL
        display dialog "I'm doing something with this URL: " & return & this_URL
    end open location
    

    然后将其保存为应用程序。然后在 Finder 中使用 Show Package Contents 编辑 Info.plist。您向应用添加一些属性以将其注册为您的协议的处理程序。

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>Cliff's handler</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>abcdef</string>
            </array>
        </dict>
    </array>
    

    【讨论】:

    • 这在 10.8.2 上对我不起作用。在使用More Internet for Mac 之类的东西将方案与应用程序关联后,我可以添加MissingLink。但我无法使用上述简单的 AppleScript 来实现这一点。如果我运行open local:test,它会显示/Users/username/local:/test does not exist
    • 好的,这是个好建议。我似乎有它的工作。我遇到了与“不存在”完全相同的问题但是在将整个 .app 文件移动到另一个目录之后,操作系统似乎拾取了它。
    • 操作系统何时实际注册这个?
    • 好的,我也搞定了。正如@counterbeing 所说,处理程序仅在您将应用程序包移动到不同(任意)位置后才起作用。这感觉很奇怪,因为 Mac OS X 似乎在 THE MOVE 事件上注册了应用程序的协议处理程序。我可以明白为什么这是有道理的,因为大多数应用程序“安装”到/Applications 目录中,只需让用户大部分时间将其拖到那里。这样,任何已安装的应用程序(无论是拖入 Applications 目录还是由 .mpkg 安装程序移入)都将注册其处理程序。
    【解决方案3】:

    这个问题已经有十年历史了(!)但是谷歌搜索把我带到了这里,所以我想提一下我刚刚发现的东西。

    Platypus 是一个开源工具,允许您从 shell 脚本或其他脚本语言创建独立的“应用程序”。虽然它实际上只是一个脚本包装器,但它确实启用了一些很酷的东西,例如对话框和菜单栏项。

    重要的是,它甚至可以让您将“应用程序”注册为您自己的自定义 URL 方案的处理程序。来自文档:

    注册为 URI 方案处理程序使应用程序注册为 URI 方案的处理程序。这些可以是标准 URI 方案,例如 http,也可以是您选择的自定义 URI 方案(例如 myscheme://)。如果您的应用程序是 URI 方案的默认处理程序,则每次打开与该方案匹配的 URL 时,它将启动 open。然后将该 URL 作为参数传递给脚本。

    设置非常简单。只需提供您的脚本,在高级设置页面上输入您想要的方案名称,然后单击以构建应用程序(这一切都是自动化的)。方案和正斜杠之后的所有内容都将作为参数传递给您的脚本。

    例如,您可以使用以下 bash 脚本作为“speak://”协议的处理程序。

    #!/usr/bin/env bash
    # The 'say' command on macOS will speak the provided text through the speaker
    say $1
    

    您可以通过在浏览器中输入speak://say-something-funny 或在命令行中使用open 命令来调用它:

    $ open "speak://hello-from-the-command-line"
    

    【讨论】:

    • 我可以设法让open -a App scheme://test 工作,但不是简单的形式open scheme://test,关于如何定义(如果可能仅使用命令)给定uri-scheme 的默认处理程序的任何想法?
    • 啊,我发现它为什么不起作用了,即使应用程序没有运行,我仍然将 LinCastor 作为默认值。删除使这项工作按预期进行。
    • 谢谢,我已经尝试了 5 个小时才能让它工作,鸭嘴兽可以工作(截至 2020 年 12 月)
    【解决方案4】:

    截至今天,我发现在 Mac 上以最少开销解决此问题的最佳方法是使用命令行 duti,它允许我在一个非常简单的文本文件中定义我的所有关联:

    brew install duti

    你需要两件事。您要关联的应用程序的第一个捆绑包 ID:

    mdls -name kMDItemCFBundleIdentifier /Applications/MacVim.app

    第二个文件类型的 UTI,Apple provides a list,但您也可以像这样探索您的应用支持的 UTI:

    mdls -name kMDItemContentTypeTree /Applications/MacVim.app

    现在在系统中的某处创建一个文本文件,将捆绑包 ID 与 UTI 相关联:

    # ~/.default-apps.duti
    #
    # bundle id       UTI                  role
    com.apple.Safari  public.html          all
    org.vim.MacVim    txmt
    org.vim.MacVim    public.ruby-script
    

    请注意,我可以关联 txmt 之类的 URL 处理程序以及 Ruby 脚本之类的文件类型。

    在该文件中,我会记录我的所有应用偏好,并在全新安装后或在其他 Mac 上获得帐户时立即重现它们:

    duti ~/.default-apps.duti
    

    【讨论】:

      【解决方案5】:

      Jay 回答中链接页面的重要部分是 Info.plist 中的条目。

      我认为使用 Launch Services,如果它是唯一可以处理特定 URL 方案的应用程序,它将自动打开此应用程序,否则您将需要使用 Charlie Martin 描述的技巧。

      我不确定需要执行的默认命令是什么,或者它是否是 launchctl 命令。

      【讨论】:

        【解决方案6】:

        挖掘细节很困难,但有一个名为RCDefaultApp 的首选项窗格会为您处理。我仍然很想知道它是如何工作的,会继续挖掘。

        【讨论】:

        • 非常感谢 - 这是我在 10.9.2 上无需思考的解决方案。为在 Sourcetree 中打开 github-mac:// 工作(这曾经为我工作!)
        【解决方案7】:

        我对 Mac 没有太多经验,因此我们将不胜感激。

        尝试借助 dutiPackages 安装程序的安装后脚本中运行添加我的自定义协议:

        #!/bin/sh
        ## 
        ##  add_handlers.sh -- register UTI handlers for the MyApp
        ##
        ##  Requires the duti tool
        ##
        
        ./duti -s MyApp myapp
        

        该处理程序出现在 RCDefaultApp 首选项窗格中,但是当从我的其他应用程序调用时,它会在地址栏中使用该协议打开 Safari,询问“您要允许此页面打开“MyApp”吗?单击允许显示错误:

        Safari 无法打开指定地址。 Safari 无法打开“myapp://”,因为 macOS 无法识别以“myapp:”开头的互联网地址。

        当尝试从终端打开时:

        deploy@mini-mac-mini ~ % open myapp://

        LSOpenURLsWithRole() 失败,URL myapp:// 出现错误 -10810。

        【讨论】:

          猜你喜欢
          • 2011-04-27
          • 2011-02-18
          • 1970-01-01
          • 2016-10-23
          • 1970-01-01
          • 2014-04-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多