通过 ScriptMonitor.app 实用程序运行 AppleScript

Dav*_* P. 2 macos applescript automation system-calls

当 AppleScript 通过系统范围的脚本菜单运行时,它们的进度会使用 ScriptMonitor 小程序(位于/System/Library/CoreServices/ScriptMonitor.app,在 OS X Yosemite 中引入)显示在菜单栏中。这使您可以随时了解正在运行的脚本、监控进度并轻松停止运行脚本。

脚本监视器图标

是否可以从脚本菜单外部通过 ScriptMonitor 运行 AppleScript,例如从终端或来自其他应用程序的系统调用?

我尝试了以下命令的各种排列,但都没有成功:

/System/Library/CoreServices/ScriptMonitor.app/Contents/MacOS/ScriptMonitor /PATH/TO/SCRIPT
Run Code Online (Sandbox Code Playgroud)

或者

open -a /System/Library/CoreServices/ScriptMonitor.app --args /PATH/TO/SCRIPT
Run Code Online (Sandbox Code Playgroud)

这很有用的原因是有许多帮助应用程序运行 AppleScripts 以响应事件,但往往不太擅长通知用户他们的成功或失败。

Dav*_* P. 5

因此,事实证明这可以使用Cocoa 框架中的NSUserScriptTask来完成,或者作为编译的命令行应用程序的一部分,或者通过 AppleScript/Objective-C (ASObjC)。

此解决方案允许从 System ScriptMonitor.app 实用程序运行 AppleScripts、Automator 工作流和 shell 脚本。


ASObjC 解决方案

此处理程序将在 OS X 10.10 Yosemite 及更高版本上本地运行。它接受一个参数,一个包含 POSIX 样式(斜线分隔)脚本路径的字符串。脚本在后台立即执行,不返回任何结果。

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)

    # The following delay was increased due to a system hang on Mojave after installation of Security Update 2020-004 (previously, the delay was 0.05).
    delay 10 -- Necessary to allow NSUserScriptTask to be dispatched before execution terminates.

    return

end runInScriptMonitor
Run Code Online (Sandbox Code Playgroud)

它被称为如下: runInScriptMonitor("/PATH/TO/FILE")

这允许您从 AppleScript 中运行 ScriptMonitor 中的脚本。如果调用放置在包装器 AppleScript 中,则可以从命令行使用osascript.


已编译的 Objective-C 解决方案

按照这些说明创建一个命令行程序,该程序将脚本路径作为输入并使用 ScriptMonitor 运行脚本。您必须安装Xcode 命令行工具(或完整的Xcode)才能编译代码。

  1. 将以下代码保存osascriptmonitor.m在 Desktop 文件夹中:

     #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:60.0f];
         }
    
         return 0;
     }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过从终端运行以下命令来编译程序:

     cd ~/Desktop
     gcc -framework Foundation osascriptmonitor.m -o osascriptmonitor
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您现在将osascriptmonitor在桌面上拥有一个名为的可执行文件。您可以从终端运行该程序,传递要在 ScriptMonitor 中运行的脚本的路径。

示例(替换/PATH/TO/SCRIPT为您要运行的脚本的路径):

    ~/Desktop/osascriptmonitor "/PATH/TO/SCRIPT"
Run Code Online (Sandbox Code Playgroud)

如果随后将可执行文件移动到/usr/local/bin,则无需指定其整个路径即可运行该程序。

    osascriptmonitor "/PATH/TO/SCRIPT"
Run Code Online (Sandbox Code Playgroud)

2020 年 1 月 3 日编辑:

直接解决方案

幸运的是,我偶然发现了一个未记录的选项,osascript这使得 AppleScripts 在很大程度上不需要上述选项:-P开关。

用法: osascript -P "/PATH/TO/SCRIPT"

就其本身而言,这将使脚本仅在脚本监视器已在运行时出现在菜单中。脚本监视器可以提前(或在脚本运行时)启动,并在所有脚本完成后自动退出。

启动脚本监视器的最佳方式是使用 -g 选项:

open -g /System/Library/CoreServices/ScriptMonitor.app
Run Code Online (Sandbox Code Playgroud)

使用此方法,除了让它出现在脚本监视器中之外,还可以轻松地将参数传递给脚本。