【问题标题】:Cocoa Scripting: How do I use AppleScript handlers (events)?Cocoa 脚本:如何使用 AppleScript 处理程序(事件)?
【发布时间】:2016-04-23 18:01:58
【问题描述】:

为我的 Mac 应用程序添加脚本功能,我想知道我是否可以从我的应用程序调用脚本末端的处理程序。如果是这样,它是如何工作的?

据我了解,处理程序就像函数(如“运行时”),可由来自脚本自身代码之外的事件调用。 Sdef 文件理解event 标签,看到我可以使用Sdef Editor 输入事件。但我在 Cocoa 脚本指南中找不到任何相关文档。

我的应用程序记录了剪贴板,所以我想知道是否可以让正在运行的脚本知道已记录了一个新的剪贴板,以便脚本可以对其进行操作。

现在,与其调用我为此类事件定位、加载和运行的单独(独立)脚本,我更希望用户可以持续运行一个脚本来声明我的应用程序随后调用的事件. (这是否真的是一个好主意不应该在这里讨论,我只是用这个作为理解 AppleScript 事件的例子。)

这可能吗?如果不是,sdef 中的事件条目是什么意思?

更新:这是 AppleScript 中处理程序的介绍:MacScripter: Getting Started with Handlers

【问题讨论】:

    标签: applescript cocoa-scripting


    【解决方案1】:

    实现 AppleScript 事件处理程序的困难在于应用程序必须永久引用该脚本。

    例如,在 Finder、消息、邮件中处理事件处理程序的脚本必须在目标应用程序中注册,以保留对脚本的引用。

    当脚本实现所提供的事件处理程序之一时,目标应用程序会创建一个NSAppleEventDescriptor

    initWithEventClass:kHandlerEventClass 
               eventID:kEventID
      targetDescriptor:kEventTargetDescriptor 
              returnID:kAutoGenerateReturnID // predefined constant in CarbonCore.h
         transactionID:kAnyTransactionID]; // predefined constant in CarbonCore.h
    

    包括参数的子描述符,并通过目标脚本引用上的executeAppleEvent 发送。

    • kEventID 是 sdef 文件 ('EfgH') 中 8 个字符代码的最低 4 个有效位。
    • kHandlerEventClass 是 sdef 文件 ('abcD') 中 8 个字符代码的最高 4 个有效位。
    • kEventTargetDescriptor 是一个 NSAppleEventDescriptor,表示客户端或目标应用程序作为返回地址。

    事件处理程序的工作方式类似于命令,这里是一个非常基本的示例

    <event name="did appear something" code="abcDEfgH" description="This handler is called when something appears.">
         <direct-parameter description="The names of the appeared something.">
            <type type="text" list="yes"/>
         </direct-parameter>
         <parameter name="with result" code="smTS" description="A record of some information about the names" type="something reply"/>
    </event>
    

    在 AppleScript 中实现了处理程序

    on did appear something theNames with result theResult
    
    • theNames 是一个文本列表
    • theResult 是自定义记录类型 something reply

    【讨论】:

    • 我已经能够通过使用硬编码的处理程序名称来调用我通过 NSAppleScript 加载的脚本的处理程序。我想这是它的清洁版本。我查看了使用此类事件的消息脚本,我想我现在可以将它们整合在一起。我想很多这些知识仍然来自 Cocoa 之前的脚本 API 和 Inside Mac,现在很难找到,因为 Apple 已经从他们的服务器中删除了所有旧文档。好像它们不再有用了:)
    • 那么,你建议我如何管理脚本和我的应用程序之间的连接?我想我的应用程序必须选择(固定名称?)并加载脚本本身,然后使用其默认处理程序(“运行时”)运行它以启动并准备好?应用程序是否还应该监视 mod 日期戳以在它更改时重新加载它?还是因为脚本可能将其属性存储在其中,从而导致以这种方式重新加载它时出现问题?或者是否有一种方法可以让用户调用脚本并且应用程序识别脚本并保持连接?跨度>
    • 通过NSAppleScript 运行脚本和将Apple 事件发送到sdef 文件中定义的处理程序是两件完全不同的事情。这取决于目标应用程序是否需要直接通知脚本特定事件的发生(单向)或使用像库这样的脚本(双向)。还有第三种方法可以将NSAppleScriptTask 与位于指定Application Scripts 文件夹中的脚本一起使用。
    • 我无法理解您的回答。我知道 NSAppleScript 和 NSAppleScriptTask。我两个都用。后者始终运行默认处理程序(运行时),而前者让我通过 executeAppleEvent 调用其他处理程序。这一切都清楚了。不过,这不是我要问的。很抱歉不清楚,但我不知道你是误解了我还是我误解了你。您回答中的前 2 个句子使它听起来更复杂,因此我的后续问题。如果我只需要让用户选择一个脚本文件并使用 NSAppleScript 加载它 - 那很容易。
    • 我刚刚回答了如何使用 sdef 文件中定义的 AppleEvents 的问题。 NSAppleScript 是另外一回事:它用于简单地运行脚本(从文字字符串源或从磁盘加载)。 NSUserAppleScriptTask(我忘了User)与NSAppleScript 非常相似——最大的区别是你不能从文字字符串编译和运行脚本,另一方面你可以在沙盒应用程序中运行脚本没有限制和特定的 Apple Events 权利。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2017-06-16
    • 2013-12-24
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    相关资源
    最近更新 更多