Macos 是否在.app上触发脚本(AppleScript或JXA)?

Macos 是否在.app上触发脚本(AppleScript或JXA)?,macos,printing,applescript,alert,javascript-automation,Macos,Printing,Applescript,Alert,Javascript Automation,我有一个小型计算机实验室,供学生在无人监督的情况下使用,并在网络上连接了一台打印机。我正在尝试实现一个简单的脚本添加警报对话框,其中包含有关打印机的所有规则,当他们从任意数量的不同应用程序中选择“打印”时,我需要弹出这些规则 我正在尝试将脚本直接附加到用户/库/打印机目录(xxx.xxx.xxx.xxx.app)中的打印机本身,以便任何浏览器或pdf查看器等在尝试运行打印机时都会显示消息 我曾尝试将automator与applescript一起使用,我曾尝试重命名打印机并将applescript

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

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

我曾尝试将automator与applescript一起使用,我曾尝试重命名打印机并将applescript称为打印机的名称,但迄今为止效果不佳


我遗漏了什么?

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

说明书
  • 打开脚本编辑器应用程序并创建新文档
  • 从窗口左上角附近的弹出窗口中,选择JavaScript而不是AppleScript
  • 粘贴下面提供的代码
  • 通过在“保存”面板中将“文件格式”更改为“应用程序”,并启用“运行后保持打开处理程序”选项,将脚本保存为小程序
  • 从“脚本”菜单中选择“运行应用程序”,运行小程序
  • 启动应用程序并注意到警报
  • 启动然后停止屏幕保护程序,并注意到一个警报
  • 代码 讨论 首先,小程序代码创建了一个名为“MainController”的新类,该类实现了两个方法“appDidLaunch:”和“screensaverDidStop:”。实现这些方法是为了使用标准添加的“显示警报”功能

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

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

    下一步 如果要从JXA运行AppleScript脚本,可以参考的答案

    如果要使意外退出小程序变得更加困难,可以通过在小程序的Info.plist中将LSUIElement键设置为“true”,将小程序设置为“UI元素”


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

    请分享您迄今为止的尝试。我的applescript现在只是一个系统事件调用,用于显示带有消息的对话框。我使该脚本成为一个只运行的应用程序,最后一行是打开PRINTER.app的命令。然后我重命名了用户文件夹“printer.app”中的打印机,并将仅运行的应用命名为打印机名称。运行脚本有效并触发了打印队列,但应用程序的第一次打印尝试创建了一台新打印机并绕过了脚本。我还尝试通过automator创建一种方法来调用脚本,但看起来最接近的方法是创建文件夹动作,在这种情况下,这似乎毫无帮助。当.app运行或调用打印机时,无法触发AppleScript。当然,你可以让脚本启动应用程序。您可以有一个始终运行的脚本,在打印过程激活时提供消息,尽管这可能会占用大量资源。是的,我现在正试图找到一些现成的解决方法。我不希望脚本持续运行,但可能有一个不太传统的解决方案。当屏幕保护程序被禁用时,可能会触发脚本?这样一来,每当一个新学生坐在一台闲置的机器前,他们都会收到这样的信息?这是一个棘手的…这是伟大的!它工作完美,资源消耗非常低,似乎我可以轻松地让appDidLaunch函数通过if循环运行,并且只有在“PRINTER.app”启动时才会弹出消息?所以不是每次打开任何应用程序,而是只有有人点击打印机时才打开?是的,没错<代码>如果(appName=='PRINTER'){…}谢谢!!这非常有效,而且你抓取应用程序名称的方式,我所需要做的就是
    if(appName==“PrinterProxy”)
    并且我发送到的任何打印机都会触发警报。干得好,谢谢你花时间@bacongravy
    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)