问题
I have a small computer lab for students to use fairly unsupervised, with a printer attached on the network. I am trying to implement a simple scripting additions alert dialog with all the rules about the printer that I need to pop up when they select print from any number of different applications.
I am trying to attach the script directly to the printer itself in the User/Library/Printer directory, (xxx.xxx.xxx.xxx.app) so any browser, or pdf viewer, etc. will get the message displayed when they try to run the printer.
I have tried using automator with applescript, I have tried renaming the printer and calling the applescript the name of the printer, so far no good.
What am I missing?
回答1:
In this answer I will show how to create a JavaScript for Automation (JXA) applet that listens for app-launch and screensaver-stop notifications and then displays an alert when it receives one, thereby producing the desired outcome described in the question. I also describe how this approach can be adapted to trigger an AppleScript script, which would produce the specific behavior described in the title of the question.
Instructions
- Open the Script Editor app and create a new document
- From the pop-up near the top-left of the window, select JavaScript instead of AppleScript
- Paste in the code provided below
- Save the script as an applet by changing the 'File Format' to 'Application' in the save panel and enabling the 'Stay open after run handler' option.
- Run the applet by choosing 'Run Application' from the 'Script' menu
- Launch an app and notice an alert
- Start and then stop the screensaver and notice an alert
Code
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)
Discussion
First, the applet code creates a new class named 'MainController', which implements two methods, 'appDidLaunch:' and 'screensaverDidStop:'. These methods are implemented to use the 'display alert' functionality from Standard Additions.
Next, the applet code instantiates an object of this class, and registers that instance as on observer of the notifications that are posted when apps are launched, and when the screensaver stops.
The applet continues to run after the JXA code executes, and when the events occur, the JXA functions are invoked.
Next Steps
If you want to run an AppleScript script from JXA, you can refer to the answer to this question.
If you want to make it harder to quit the applet accidentally, you can make the applet a 'UI Element' by setting the LSUIElement key to 'true' in the applet's Info.plist.
Finally, you might want to add the applet to the user's Login Items so that it starts automatically after a reboot.
来源:https://stackoverflow.com/questions/49501983/trigger-a-script-applescript-or-jxa-on-app-running