【问题标题】:Running AppleScripts through the ScriptMonitor.app Utility通过 ScriptMonitor.app 实用程序运行 AppleScript
【发布时间】:2016-03-08 22:56:39
【问题描述】:

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

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

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

/System/Library/CoreServices/ScriptMonitor.app/Contents/MacOS/ScriptMonitor /PATH/TO/SCRIPT

open -a /System/Library/CoreServices/ScriptMonitor.app --args /PATH/TO/SCRIPT

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

【问题讨论】:

    标签: macos automation applescript system-calls


    【解决方案1】:

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

    此解决方案允许从 System ScriptMonitor.app 实用程序运行 AppleScript、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
    

    调用如下:runInScriptMonitor("/PATH/TO/FILE")

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


    编译的 Objective-C 解决方案

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

    1. 在桌面文件夹中将以下代码另存为osascriptmonitor.m

       #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;
       }
      
    2. 通过从终端运行以下命令来编译程序:

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

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

        ~/Desktop/osascriptmonitor "/PATH/TO/SCRIPT"
    

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

        osascriptmonitor "/PATH/TO/SCRIPT"
    

    2020 年 1 月 3 日编辑:

    直接解决方案

    幸运的是,我偶然发现了 osascript 的一个未记录选项,这使得 AppleScripts 基本上不需要上面的选项:-P 开关。

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

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

    启动 Script Monitor 的最佳方式是使用 -g 选项:

    open -g /System/Library/CoreServices/ScriptMonitor.app
    

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

    【讨论】:

    • 这很有帮助。您是否知道通过 ScriptMonitor 运行这些脚本,同时向它们传递参数/参数?
    • 看起来没有任何简单的方法可以将参数传递给 NSUserScriptTask... 您可以生成一个临时的 trampoline 脚本,该脚本将使用参数执行主脚本,并将 trampoline 脚本路径传递给上面的处理程序。 trampoline 脚本必须手动处理不同类型的主要脚本(例如 AppleScript、shell 等),而 NSUserScriptTask 通常透明地处理这些脚本。
    • Mojave 安全更新 2020-004 会在运行需要辅助功能权限的脚本后,如果程序退出过快导致系统锁定;我已经增加了上面的睡眠/延迟来反映这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多