【问题标题】:Trigger a script (AppleScript or JXA) on .app running?在 .app 运行时触发脚本(AppleScript 或 JXA)?
【发布时间】:2018-09-05 05:15:21
【问题描述】:

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

我正在尝试将脚本直接附加到用户/库/打印机目录 (xxx.xxx.xxx.xxx.app) 中的打印机本身,因此任何浏览器或 pdf 查看器等都会显示消息当他们尝试运行打印机时。

我尝试过使用带有 applescript 的 automator,我尝试过重命名打印机并将 applescript 称为打印机的名称,但到目前为止还不行。

我错过了什么?

【问题讨论】:

  • 请分享您到目前为止所尝试的内容。
  • 我的 applescript 现在只是一个系统事件调用,用于显示带有消息的对话框。我使该脚本成为仅运行的应用程序,最后一行是打开 PRINTER.app 的命令。然后我在用户文件夹“PRINTER.app”中重命名了打印机,并将仅运行应用程序命名为打印机名称。运行脚本有效并触发了打印队列,但应用程序的第一次打印尝试创建了一个新打印机并绕过了脚本。
  • 我也尝试通过自动机创建一种方法来调用脚本,但看起来我能得到的最接近的是创建一个文件夹操作,这在这种情况下似乎根本没有帮助.
  • 当 .app 运行或打印机被调用时,您不能触发 AppleScript。当然,您可以让脚本启动应用程序。您可以有一个始终运行的脚本,在打印过程激活时提供消息,尽管这可能会占用大量资源。
  • 是的,我现在正在尝试寻找某种开箱即用的解决方法。我不希望持续运行脚本,但也许可以使用不太传统的解决方案。也许禁用屏幕保护程序时可以触发脚本?这样每次新学生坐在闲置的机器上时,他们都会收到信息?这个有点棘手……

标签: macos printing applescript alert javascript-automation


【解决方案1】:

在这个答案中,我将展示如何创建一个用于自动化的 JavaScript (JXA) 小程序,该小程序侦听应用程序启动和屏幕保护程序停止通知,然后在收到通知时显示警报,从而产生问题中描述的所需结果.我还描述了如何调整这种方法来触发 AppleScript 脚本,该脚本会产生问题标题中描述的特定行为。

说明

  1. 打开脚本编辑器应用并创建一个新文档
  2. 从窗口左上角附近的弹出窗口中,选择 JavaScript 而不是 AppleScript
  3. 粘贴下面提供的代码
  4. 通过在保存面板中将“文件格式”更改为“应用程序”并启用“运行处理程序后保持打开”选项,将脚本保存为小程序。
  5. 从“脚本”菜单中选择“运行应用程序”来运行小程序
  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”的新类,它实现了两个方法,“appDidLaunch:”和“screensaverDidStop:”。实现这些方法是为了使用标准添加中的“显示警报”功能。

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

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

后续步骤

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

如果您想让小程序更难意外退出,可以通过在小程序的 Info.plist 中将 LSUIElement 键设置为“true”,使小程序成为“UI 元素”。

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

【讨论】:

  • 这太棒了!它运行良好,并且资源消耗非常低,似乎我可以轻松地使 appDidLaunch 函数通过 if 循环运行,并且仅在“PRINTER.app”启动时才弹出消息?所以不是每次打开任何应用程序时都会出现这种情况,而是只有在有人点击打印机时才会出现这种情况?
  • 是的,完全正确! if (appName == ‘PRINTER’) { ... }
  • 谢谢!!这很好用,而且你获取应用程序名称的方式,我需要做的就是if (appName == 'PrinterProxy') 和我发送给的任何打印机都会触发警报。干得好,感谢您抽出宝贵时间@bacongravy
猜你喜欢
  • 2016-02-11
  • 2018-03-19
  • 2019-09-17
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2020-07-10
相关资源
最近更新 更多