如何在 macOS 沙盒环境中从 C++ 运行 AppleScript 而不会侵犯权利

2024-03-08

我正在尝试使用AppleScript来控制ApplePhotos来自 QT C++ 应用程序中的应用程序,该应用程序必须在 macOS App Store 所需的沙箱环境中运行。

我尝试通过 QProcess 启动来运行 AppleScriptosascript, 像这样 :

const QString aScript = QString(
        "tell application \"Photos\"\n"
        "    set selMedia to (get media items whose id contains \"%1\")\n"
        "    if not (album \"Trash from %2\" exists) then\n"
        "        make new album named \"Trash from %2\"\n"
        "    end if\n"
        "    add selMedia to album \"Trash from %2\"\n"
        "end tell").arg(fileNameNoExt, APP_NAME);
QProcess script;
script.setProgram("osascript");
script.setArguments(QStringList() <<
                     "-e" << aScript);
script.start();
script.waitForFinished(); 
int exitCode = script.exitCode();
if(exitCode!=0){
    QString outMsg = script.readAllStandardOutput();
    QString errorOut = script.readAllStandardError();
    // Warn user and output message... 
}

这在沙箱之外工作得很好,将库中所需的项目添加到所需的相册中。然而,在沙箱内,我得到了errAEPrivilegeError。寻找在Console对于错误事件,它指出:

AppleEvents/sandbox: Returning errAEPrivilegeError/-10004 and denying dispatch of event core/getd from process '<private>'/0x0-0x4d84d8, pid=31654, because it is not entitled to send an AppleEvent to this process.

这是我签署应用程序时的权利文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.files.user-selected.read-write</key>
        <true/>
    <key>com.apple.security.app-sandbox</key>
        <true/>
    <key>com.apple.security.scripting-targets</key>
    <dict>
        <key>com.apple.Photos</key>
        <array>
            <string>com.apple.Photos.library.read-write</string>
        </array>
    </dict>
  </dict>
</plist>

当应用程序首次运行(沙盒)并启动 AppleScript 时,我收到系统权限框,表示该应用程序要求控制“照片”应用程序。当然,我单击“确定”,但随后出现错误。在下次运行时,由于已经授予了权限,因此不会出现系统权限框,但它仍然会失败。当我使用终端命令重置权限时tccutil reset All [my app bundle id],然后在下次执行应用程序和 AppleScript 时,我再次获得权限框。

如果我删除com.apple.security.scripting-targets权利,我没有收到系统权限请求,并且错误不同:从我的应用程序中,错误输出表明照片未运行,从控制台它说由于沙箱而被拒绝。如果我保留 scripting-targets 和 com.apple.Photos 但删除 library.read-write 我会再次收到 errAEPrivilegeError 。

我试图只测试make new album named "Trash [...]"但这仍然失败并出现 errAEPrivilegeError。即使只告诉照片quit与AppleScript(根据Photos.app/Contents/Resources/Photos.sdef除了脚本之外不需要任何特定权限,我还得到 errAEPrivilegeError。唯一有效的命令是activate.

另外,如果我尝试不将 qprocess 作为单独的进程运行,QProcess::execute(如果沙箱问题可能是因为它不是运行脚本的主应用程序?),我仍然得到相同的 errAEPrivilegeError。

我缺少什么才能让它工作,或者在沙箱中时我应该使用什么其他方法从 C++/QT 运行 applescript ?


你包括了吗NSAppleEventsUsageDescription https://developer.apple.com/documentation/bundleresources/information_property_list/nsappleeventsusagedescription?language=objc在你应用程序的 Info.plist 中?

[ETA]

好的,经过进一步挖掘,我可以确认您所看到的行为。有了正确的应用程序权利,进程中的NSAppleScript可以将 AE 发送到照片;但是,同一进程无法从子进程发送 AEosascript过程。

根据苹果文档 https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html(这很糟糕),子进程必须恰好有 2 个权利才能继承其父进程:com.apple.security.app-sandbox and com.apple.security.inherit。然而,运行codesign --display --entitlements - /usr/bin/osascript shows osascript没有这些,但有一堆不相关的权利。所以这看起来像是苹果在构建方式上搞砸了osascript.

当运行属于 Swift/ObjC 应用程序一部分的 AppleScripts 时,我通常建议使用 AppleScript-ObjC 桥 https://github.com/hhas/Swift-AppleScriptObjC直接加载并调用您的 AppleScript 处理程序;不需要子流程。但我不知道如何在 Qt 应用程序中做到这一点。

最简单的解决方案可能是在 ObjC 中编写您自己的命令行可执行文件/XPC 服务,它通过以下方式运行您的 AppleScript 代码NSAppleScript,给它com.apple.security.app-sandbox and com.apple.security.inherit权利,并将其嵌入到 Qt 应用程序的主包中。

(您可能还需要添加com.apple.security.automation.apple-events如果运行时经过强化,则在主应用程序的权利中。)

还有一件事:避免生成 AppleScript 代码通过字符串插值 https://en.wikipedia.org/wiki/Code_injection。如果要参数化脚本,请将值打包为 Apple 事件中的参数并调用相应的 AS 处理程序via -executeAppleEvent:error: https://stackoverflow.com/questions/6963072/execute-applescript-from-cocoa-app-with-params/7002611#7002611.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 macOS 沙盒环境中从 C++ 运行 AppleScript 而不会侵犯权利 的相关文章

  • 当给定 100k 项时,QListView 需要很长时间才能更新

    我在读取文件时遇到问题 具体是我想制作一本小字典 在我需要阅读的文件中有这样的内容 a Ph P6 a snsr CA a b c fb Dj a b c book i BS A except B gate oOPa y a font kQ
  • C++0x 初始值设定项列表示例

    我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • std::bind2nd 和 std::bind 与二维数组和结构数组

    我知道 C 有 lambda 并且 std bind1st std bind2nd 和 std bind 已弃用 然而 从C 的基础开始 我们可以更好地理解新特性 所以 我从这个非常简单的代码开始 使用int 数组s 第一个例子 与std
  • 何时使用 C++ 私有继承而不是组合?

    你能给我一个具体的例子吗 什么时候使用私有继承优于组合 就我个人而言 我将使用组合而不是私有继承 但在某些情况下 使用私有继承可能是特定问题的最佳解决方案 正在阅读C faq http www parashift com c faq lit
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • 尽管浮点数相同,但它们并不相等? [复制]

    这个问题在这里已经有答案了 下面的程序输出This No is not same 当两个数字相同时为什么会这样做 void main float f 2 7 if f 2 7 printf This No is same else prin
  • C语言中没有循环可以打印数组吗?

    例如 在Python中 如果我们将一个列表作为数组 它会直接用一行代码打印整个数组 有什么办法可以用C语言实现同样的事情吗 简短回答 No 对表格上几乎所有问题的简短回答 用 C 语言做 X 工作能像用 Python 一样简单吗 No 长答
  • 主构造函数不再在 VS2015 中编译

    直到今天 我可以使用主构造函数 例如 public class Test string text private string mText text 为了能够做到这一点 在以前的 Visual Studio CTP 中 我必须将其添加到 c
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • 何时分离或加入 boost 线程?

    我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 如果项目包含多个文件夹,如何使用 Add-Migration

    我想Add Migration使用我的 DbContext 但出现错误 The term add migration is not recognized as the name of a cmdlet function script fil
  • List 或其他类型上的 string.Join

    我想将整数数组或列表转换为逗号分隔的字符串 如下所示 string myFunction List
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 使用 WinAPI 连接禁用的显示设备

    我的问题是启用禁用的监视器ChangeDisplaySettingsEx 我想这不是火箭科学 但经过一番挖掘后 它看起来仍然是不可能的 我找到了一种根据找到的 Microsoft 代码示例禁用所有辅助显示器的方法here https msd
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以
  • 在两个点之间创建一条曲线,每个点都具有标准化向量

    因此 我需要一种写入方法来在两点之间创建一条曲线 每个点都有一个指向任意方向的归一化向量 我一直在尝试设计这样一种方法 但一直无法理解数学 在这里 由于一张图片胜过一千个文字 这就是我所需要的 在图中 矢量垂直于红线 我相信向量需要进行相同
  • boost::spirit::qi::语法和可变参数模板

    我在使用可变参数模板定义语法时面临一个问题 我首先定义一些包含在某些结构中的简单语法 例如纬度 经度 如下所示 include
  • 是否可以检测流是否已被客户端关闭?

    简要介绍一下情况 我有一项服务可以通过套接字接收信息并发送回复 连接不安全 我想设置另一个可以为这些连接提供 TLS 的服务 这个新服务将提供单个端口并根据提供的客户端证书分发连接 我不想使用 stunnel 有几个原因 其中之一是每个接收

随机推荐

  • PHP会话变量从子域到主域

    我在亚马逊 Web 服务器 EC2 实例上的 ISPConfig 中设置了 2 个域 站点 我有一个名为app example com http www app example com另一个是https www example com ht
  • 在 Android 中设计国际象棋

    我通过使用表格布局中的按钮为国际象棋游戏设计了一个用户界面 对于棋子 我采用 ASCII 值并将其作为字符串值打印在按钮上 但我不知道单击按钮时如何获取该值 这是我第一次为Android 编程
  • 如何使 find() 能够处理一组结构?

    我正在使用一个set保存包含多个字符串的结构 我希望能够使用find 集的功能 但是 由于该集合保存结构 因此它不起作用 我想find 仅查看结构中的字符串之一 如何才能做到这一点 这是我尝试使用的代码 除了以下部分之外 它工作正常find
  • PHP isset($this) 并在静态和对象上下文中使用相同的对象方法

    我正在开发一个需要通过静态函数调用和对象方法访问的类 我发现的一件事是我在多个函数之间重复逻辑 简化示例 class Configurable protected configurations array protected static
  • iOS 应用程序的 Firebase 3.7.0 上的链接错误

    我尝试在我的 iOS 应用程序中使用 Firebase SDK 3 7 0 但它出现链接错误 我已按照 README md 中描述的步骤进行操作 该文件包含在从下载的框架 SDK 中https firebase google com doc
  • 渐变 IE8+ 所需的最低 CSS

    通常当我制作渐变时我使用colorzilla 渐变编辑器 http www colorzilla com gradient editor 默认情况下 它会为您生成 CSS 这是一个例子 background 1e5799 Old brows
  • ruby on Rails 如何删除文件routes.rb中的一行

    在我的文件routes rb中 namespace admin do resources albums except new edit destroy resources conversation replies except new ed
  • 有人提出了 javascript 的 Pipe 运算符吗?

    许多语言都有一个运算符 允许您将一个操作的结果通过管道传输到对另一个操作的调用中 例如 bash 中的运算符 gt F 中的运算符 在我看来 JavaScript 中方法链接的常见习惯用法的一大优点是它从上到下 从左到右读取 var foo
  • 视图更新后,旋转器动画开始弹跳

    我有一个图像 我对其应用了 360 度旋转以产生加载 旋转的效果 它工作正常 直到我在下面添加文本 图像仍然旋转 但垂直弹跳 这是查看它的代码 import SwiftUI main struct SpinnerApp App var bo
  • 安装 Kafka 作为 Windows 服务

    如何将 Apache Kafka 作为 Windows 服务安装并运行 现在我需要进入命令提示符并启动zookeeper和kafka服务器 有什么方法可以让我将 Apache Kafka 安装为 Windows 服务吗 我只看到下面的博客
  • 为什么我的 Google App Engine Mail API 调用仍然会导致 DeadlineExceededError,尽管将它们放入任务队列中?

    我有一个 Python 函数 它为我的邮件列表中的每个电子邮件地址添加一个任务队列 每次邮寄数千个 问题是 即使每封邮件都是通过任务队列中的执行发送的 我仍然遇到这个可怕的错误 DeadlineExceededError The API c
  • 正则表达式模式忽略多个文件夹

    忽略多个文件和文件夹的正确语法是怎样的电子包装机 https www npmjs com package electron packager 只有一个参数 例如 ignore docs 效果很好 但我想忽略多个文件夹和文件 例如 ignor
  • R中如何判断列表是否为空?

    本质上 我有一个创建 list 输出的函数 我希望我的函数不创建 list 而是用另一个值 例如 NULL 或字符串 替换它 有没有办法确定变量是否分配给空列表list 空列表为空 它没有元素 但仍然是一个列表 没有元素的列表的长度为 0
  • 如何解决 ClassNotFoundException?

    我正在尝试运行 Java 应用程序 但收到此错误 java lang ClassNotFoundException 冒号后面是缺少的类的位置 但是 我知道该位置不存在 因为该类位于其他地方 我怎样才能更新该类的路径 和类路径有关系吗 类路径
  • 我如何将小胡子中的变量大写

    我的小胡子模板中有一个名为 type 的变量 我想使用标题大小写将 type 的值大写 这可能吗 考虑到该类型不是网页上显示的类型 它存储一个值 type 你可以将它包裹在一个span并使用CSS CSS capitalize text t
  • 用C语言从M68k RAM地址获取特定字节

    通过 IDA 反汇编程序我到达了这个地址 0010FD74 00 00 00 00 00 00 03 00 00 00 00 00 82 03 80 02 现在我需要给定地址来获取特定字节 例如第 7 个位置有 03 我尝试过使用C语言来做
  • Android:将imageview转换为位图,转换为灰度,位图转换为imageview

    当我编译此代码时 我没有在 Eclipse 上收到任何警告 但是当我在设备或模拟器上运行它时 该程序被迫关闭 public class MainActivity extends Activity ImageView img Button b
  • 如何卸载 Ruby on Rails 并进行全新安装?

    我正在学习 Rails 教程 我遇到 RVM 版本问题并且收到很多错误 我想从 Ruby Rails Gemfiles 等的干净版本开始 谁能给我一些关于如何卸载 Ruby on Rails 环境的简短说明 尝试这个 rvm get hea
  • 在 PHP 7 中全局启用“strict_types”

    我目前正在将我的网站从 PHP5 迁移到 PHP7 并且我已经开始使用添加的严格类型功能 然而 这要求我以下行开头所有文件
  • 如何在 macOS 沙盒环境中从 C++ 运行 AppleScript 而不会侵犯权利

    我正在尝试使用AppleScript来控制ApplePhotos来自 QT C 应用程序中的应用程序 该应用程序必须在 macOS App Store 所需的沙箱环境中运行 我尝试通过 QProcess 启动来运行 AppleScripto