在 .app 运行 上触发脚本(AppleScript 或 JXA)?

Trigger a script (AppleScript or JXA) on .app running?

我有一个小型计算机实验室,供学生在无人监督的情况下使用,并在网络上连接了一台打印机。我正在尝试实现一个简单的脚本添加警报对话框,其中包含有关打印机的所有规则,当它们 select 从任意数量的不同应用程序打印时,我需要弹出这些规则。

我正在尝试将脚本直接附加到 User/Library/Printer 目录中的打印机本身,(xxx.xxx.xxx.xxx.app) 这样任何浏览器或 pdf 查看器等都会在它们时显示消息尝试 运行 打印机。

我试过将 automator 与 applescript 一起使用,我试过重命名打印机并将 applescript 称为打印机的名称,但到目前为止效果不佳。

我错过了什么?

在这个回答中,我将展示如何创建一个 JavaScript for Automation (JXA) applet,它侦听 app-launch 和 screensaver-stop 通知,然后在收到通知时显示警报,从而产生问题中描述的预期结果。我还描述了如何调整这种方法来触发 AppleScript 脚本,这将产生问题标题中描述的特定行为。

说明

  1. 打开脚本编辑器应用并创建一个新文档
  2. 从 pop-up 到 window 的 top-left 附近,select JavaScript 而不是 AppleScript
  3. 粘贴下面提供的代码
  4. 通过在保存面板中将 'File Format' 更改为 'Application' 并启用 'Stay open after run handler' 选项,将脚本保存为小程序。
  5. 运行 小程序,方法是从 'Script' 菜单中选择 'Run Application'
  6. 启动应用程序并注意警报
  7. 启动然后停止屏幕保护程序并注意到警报

代码

var me = Application.currentApplication(); me.includeStandardAdditions = true

ObjC.import('Cocoa')

ObjC.registerSubclass({
  name: 'MainController',
  methods: {
    'appDidLaunch:': {
      types: ['void', ['id']],
      implementation: function(notification) {
        var appName = notification.userInfo.objectForKey('NSApplicationName').js
        me.activate()
        me.displayAlert(`Hello, ${appName}!`, {message: 'Nice to meet you.'})
        Application(appName).activate()
      }
    },
    'screensaverDidStop:': {
      types: ['void', ['id']],
      implementation: function(notification) {
        me.activate()
        me.displayAlert('Goodbye, screensaver!', {message: 'It was nice knowing you.'})
      }
    }
  }
})

var controller = $.MainController.new

$.NSWorkspace.sharedWorkspace.notificationCenter.addObserverSelectorNameObject(controller, 'appDidLaunch:', $.NSWorkspaceDidLaunchApplicationNotification, undefined)

$.NSDistributedNotificationCenter.defaultCenter.addObserverSelectorNameObject(controller, 'screensaverDidStop:', 'com.apple.screensaver.didstop', undefined)

讨论

首先,小程序代码新建一个名为'MainController'的class,它实现了'appDidLaunch:'和'screensaverDidStop:'两个方法。实现这些方法是为了使用 Standard Additions 中的 'display alert' 功能。

接下来,小程序代码实例化此 class 的 object,并将该实例注册为应用程序启动时和屏幕保护程序停止时发布的通知的观察者。

小程序在JXA代码执行后继续运行,当事件发生时,调用JXA函数。

后续步骤

如果你想运行来自JXA的AppleScript脚本,你可以参考this question的答案。

如果你想让小程序更难意外退出,你可以通过在小程序的 Info.plist 中将 LSUIElement 键设置为 'true' 来使小程序成为 'UI Element'。 =12=]

最后,您可能希望将小程序添加到用户的登录项,以便它在重新启动后自动启动。