问题
When AppleScripts are run through the system-wide Script Menu, their progress is displayed in the menu bar using the ScriptMonitor applet (located in /System/Library/CoreServices/ScriptMonitor.app
, introduced in OS X Yosemite). This allows you to stay aware of running scripts, monitor progress, and easily stop running scripts.
Is it possible to run AppleScripts through the ScriptMonitor from outside the Script Menu, for example from Terminal or from system calls from other applications?
I have tried various permutations of the following commands, all without success:
/System/Library/CoreServices/ScriptMonitor.app/Contents/MacOS/ScriptMonitor /PATH/TO/SCRIPT
or
open -a /System/Library/CoreServices/ScriptMonitor.app --args /PATH/TO/SCRIPT
The reason this would be useful is that there are many helper applications that run AppleScripts in response to events, but tend not to be very good at notifying the user about their success or failure.
回答1:
So, it turns out this can be done using NSUserScriptTask from the Cocoa frameworks, either as part of a compiled command-line application or through AppleScript/Objective-C (ASObjC).
This solution allows AppleScripts, Automator workflows, and shell scripts to be run from the System ScriptMonitor.app utility.
ASObjC Solution
This handler will run natively on OS X 10.10 Yosemite and later. It takes a single parameter, a string containing the POSIX-style (slash-delimited) path to the script. The script is executed immediately in the background, and no result is returned.
use framework "Foundation"
to runInScriptMonitor(script_path)
set {script_task, url_error} to current application's NSUserScriptTask's alloc()'s initWithURL:(script_path as POSIX file) |error|:(reference)
if url_error is not missing value then error (url_error's localizedDescription as string) number (url_error's code as integer)
script_task's executeWithCompletionHandler:(missing value)
delay 0.05 -- Necessary to allow NSUserScriptTask to be dispatched before execution terminates.
return
end runInScriptMonitor
It is called as follows: runInScriptMonitor("/PATH/TO/FILE")
This allows you to run scripts in ScriptMonitor from within AppleScript. If the call is placed in a wrapper AppleScript, the wrapper script can then be called from the command line using osascript
.
Compiled Objective-C Solution
Follow these instructions to create a command-line program that takes the script path as input and runs the script using ScriptMonitor. You must have the Xcode Command Line Tools (or the full Xcode) installed in order to compile the code.
Save the following code as
osascriptmonitor.m
in the Desktop folder:#import <Foundation/Foundation.h> int main(int argc, const char *argv[]) { if (argc < 2) { printf("usage: osascriptmonitor /path/to/script\n"); } else { NSString *script_path = [NSString stringWithUTF8String:argv[1]]; NSUserScriptTask *script_task = [[NSUserScriptTask alloc] initWithURL:[NSURL fileURLWithPath:script_path] error:nil]; [script_task executeWithCompletionHandler:nil]; [NSThread sleepForTimeInterval:0.1f]; } return 0; }
Compile the program by running the following commands from Terminal:
cd ~/Desktop gcc -framework Foundation osascriptmonitor.m -o osascriptmonitor
You will now have an executable file named
osascriptmonitor
on your Desktop. You can run that program from Terminal, passing the path of the script that you want to run in ScriptMonitor.Example (replace
/PATH/TO/SCRIPT
with the path of the script you want to run):~/Desktop/osascriptmonitor "/PATH/TO/SCRIPT"
If you then move the executable file to
/usr/local/bin
, you can run the program without having to specify its entire path.osascriptmonitor "/PATH/TO/SCRIPT"
来源:https://stackoverflow.com/questions/34081057/running-applescripts-through-the-scriptmonitor-app-utility