Applescript 检查蓝牙文件交换何时完成

Applescript check when a Bluetooth file exchange is complete

在上一个问题中,我询问了有关为蓝牙文件交换创建 Applescript 的问题。我现在想(如果可能的话)检查当前是否有正在进行的交换,如果有,在另一个文件通过之前等待它完成,创建某种队列。

使用我当前的代码,如果您尝试在另一个文件已经在传输过程中传输另一个文件,它只会产生错误,从而破坏整个自动化过程。

我当前的自动化设置如下。我有另一个自动化检测文件何时添加到我相机的 SD 卡,然后将其重命名为 "HP.jpg" 并将其传输到 ImagesPrint 文件夹(如下),激活此:

移动后,使用时间重命名,因此没有重复。

我计划同时将多张图像 (15-20) 放入相机 sd 文件夹中,并且这种 "queue" 到 "slow it down" 的方式只有一个可以完成整个过程一次处理,所以文件传输不会被阻塞。

我相信我有办法让您确定蓝牙文件 t运行sfer 是否正在进行中,或者更有用地确定蓝牙文件 t运行sfer 何时完成或终止.

边栏:GUI 脚本

我回答的第一部分是题外话,主要是因为我无法在我的系统上使用 AppleScript 来启动文件 t运行sfer 通过使用 send 命令 蓝牙文件交换 应用程序。我不知道为什么,我 运行 没有耐心来诊断它。因此,我使用 AppleScript GUI 脚本直接与 蓝牙文件交换 应用程序 GUI 交互,并物理控制文件发送过程。

(当然,这意味着我必须从弹出的对话框中手动 select 文件,这很好地满足了我的需要。)

我将把我的脚本放在这里作为其他可能感兴趣的人的参考,即使它与您的问题无关。我不能特别推荐这种方法,因为它不是很健壮,而且 AppleScript 在一个 运行 期间偶尔会无缘无故地抛出错误,但在接下来的 5 或 6 运行 秒内将完全正常运行,所以有点不稳定。我 运行 在 MacOS 10.13 上安装这个:

    activate application "Bluetooth File Exchange"

    tell application "System Events" to tell application process "Bluetooth File Exchange"

        tell menu item "Send File…" of menu "File" of menu bar item "File" of menu bar 1 to ¬
            perform action "AXPress"

        repeat while (exists window "Select File to Send")
        end repeat

        set W to a reference to (first window whose name begins with "Send")

        tell W
            set SendButton to button "Send"
    
            set R to a reference to rows of table 1 of scroll area 1
            set T to a reference to (static texts of UI element 1 of R whose value is Device)
            set U to a reference to value of attribute "AXParent" of T
            set [D] to a reference to value of attribute "AXParent" of U
    
            select D
    
            set start_time to do shell script "date +%Y-%m-%d\ %H:%M:%S"
    
            click SendButton
        end tell
(*
        repeat while (exists W)
        end repeat

        (*** File transfer started ***)

        set W to a reference to window "Bluetooth File Exchange"

        repeat until (exists W)
        end repeat

        repeat while (exists W)
            delay 2
        end repeat

        (*** File transfer finished ***)
*)
    end tell

当一个人以这种方式与应用程序进行物理交互时,在文件 t运行sfer 期间会出现进度 window。纯粹作为练习,我结合了对这个 window 的监控,因为它的外观 运行ce 可以标记文件 t运行sfer 何时开始;然后再次消失运行ce 以标记文件 t运行sfer 何时完成。它工作得很好,但显然不是针对您的特定情况的解决方案,因此在上面的代码中对这些行进行了块注释。

回到正题

在我的计算机上对各种日志文件进行了大量梳理之后,我设法分离出两个有用的日志条目,这些条目是在蓝牙文件 t运行sfer.log 中写入的。由于这样的文件 t运行sfers 将被系统记录下来,它提供了一种可靠的方法来确定蓝牙文件 t运行sfer 何时开始(或已经开始)以及何时完成(或完成) .

可以使用 shell 命令 log 访问日志数据,并使用指定参数进行过滤。请注意,我选择的参数不是唯一可用的参数,也不是唯一可用于确定蓝牙文件 t运行sfer 的 start/stop 的参数。在日志的不同部分,我确实注意到报告了并行事件消息,这些消息与我最终确定的消息一样可靠地排列在一起。我选择了我的特定 subsystemcategory,因为这些数据中包含的消息是人类可读的英语,并且对于正在发生的事件非常明确。

我创建了相关的 shell 命令并将其存储在 AppleScript 变量中:

    set command to "log show --predicate " & ¬
        "'(subsystem == \"com.apple.bluetooth\") && (category == \"bluetoothd\")'" & ¬
        " --start \"" & start_time & "\" --style json " & ¬
        "| grep 'EVENT: Disconnection Complete'"

然后,就在文件 t运行sfer 被激活之前(即就在我的脚本单击 Send 按钮之前),我获得了 t[=93= 的开始日期和时间]sfer(如您在上面的脚本中所见:set start_time to do shell script ...),然后持续监视日志以查找在此时间戳后出现的相应消息,该消息报告蓝牙 t运行sfer:

    repeat
        try
            set disconnected to do shell script command
            if disconnected contains "EVENT: Disconnection Complete" then ¬
                exit repeat
        end try
        delay 2
    end repeat

写入日志的消息非常清楚EVENT: Disconnection Complete,当在其日志条目的完整上下文中读取时,报告蓝牙设备断开连接以响应文件 t 的终止运行sfer(成功或失败)。我在 do shell script 中使用 grep 命令来过滤日志条目并仅隔离那部分文本。

因此,在上面的 repeat 循环中,do shell script 大部分时间都在抛出错误(非常正确),因为缺少此文本意味着 grep 无法到 return 一个值。当日志条目最终出现时,grep 找到它并 return 删除它,这允许 repeat 循环结束。

同样,当蓝牙文件 t运行sfer 开始时,有一条事件消息写入日志,报告一个 OBEX Object Push,另一个同时报告一个 OBEX File Transfer。这些是蓝牙 t运行sfer 开始的非常明确的标记,但是我没有理由专门监视这些日志条目是否出现,因为脚本控制确定文件 t运行sfer 将开始。

将此方法集成到您的工作流程中

将 AppleScript 的后两个片段添加到您的 运行 AppleScript 操作中可以让您摆脱 Pause动作,因为 AppleScript 将继续 运行—陷入其 repeat 循环,直到 文件 t运行sfer 完成。

首先,将这一行粘贴到 tell application "Bluetooth File Exchange" to send... 语句之前:

    set start_time to do shell script "date +%Y-%m-%d\ %H:%M:%S"

接下来,将其余的日志监控代码粘贴到 tell application... 语句之后。所以你的 运行 AppleScript 动作现在看起来像这样:

    set MF to (POSIX path of "Macintosh HD:Users:max:Desktop:ImagesPrint:HP.jpg") as string
    set Adr_Device to "     "

    set start_time to do shell script "date +%Y-%m-%d\ %H:%M:%S"

    tell application "Bluetooth File Exchange" to send file MF to device Adr_Device

    set command to "log show --predicate " & ¬
        "'(subsystem == \"com.apple.bluetooth\") && (category == \"bluetoothd\")'" & ¬
        " --start \"" & start_time & "\" --style json " & ¬
        "| grep 'EVENT: Disconnection Complete'"

    repeat
        try
            set disconnected to do shell script command
            if disconnected contains "EVENT: Disconnection Complete" then ¬
                exit repeat
        end try
        delay 2
    end repeat

如果您对日志条目的整体情况感到好奇(但仍按子系统和类别过滤),您可以检查 JSON 格式的输出 here,在此期间两个单独的蓝牙文件 t运行sfers 开始和完成。