swift 从macOS应用程序调用时,使用“键码”的applescript中出现错误1002

xcitsw88  于 2023-03-11  发布在  Swift
关注(0)|答案(4)|浏览(233)

我尝试从macOS应用(莫哈韦,Xcode 10.3)运行AppleScript,但是当从该应用运行AppleScript时,我收到以下错误:
/Users/my_username/Desktop/test_apple_script.scpt: execution error: System Events got an error: osascript is not allowed to send keystrokes. (1002)
根据其他帖子,我已经确保我的应用程序可以控制我的电脑(系统首选项〉安全和隐私〉隐私〉辅助功能),它也可以控制系统事件(系统首选项〉安全和隐私〉隐私〉自动化)。
下面是我的AppleScript:

tell application "System Events"
    key code 48 using {command down}
end tell

脚本在脚本编辑器中运行时可以工作(我只需要在系统首选项〉安全与隐私〉隐私〉辅助功能中给予脚本编辑器访问权限)。
这是我用于从应用程序运行Apple Script的代码(通过osascript):

let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript","/Users/my_username/Desktop/test_apple_script.scpt"]
proc.launch()

当我运行一个只显示通知的简单AppleScript时,这段代码可以完美地工作:

tell application "System Events"
    display dialog "Test"
end tell

如何使AppleScript从macOS应用程序运行,就像在脚本编辑器中运行一样?

**编辑:**对于更多的上下文,这里的命令选项卡情况只是一个例子。我试图找到一种通用的方法,通过点击应用中的按钮来模拟键盘快捷键(例如,用户点击“剪切”按钮,应用的行为就像用户刚刚按下命令+ x)。可能有一种比使用AppleScript更好的方法,但我知道使用AppleScript可以做我想做的事情。
**编辑:**如果我最初的问题不清楚,显示通知的简单AppleScript已经在我的应用程序中工作。当我试图运行模拟用户键盘输入的AppleScript时,问题出现了。
**编辑:**这里的代码暂时对我有效,但它不再有效。我根本没有更改代码。我只是再次运行我的应用程序。

let PlayPauseScript = "tell application \"Spotify\"\n playpause\n end tell"\"test\"\n end tell"
if let scriptObject = NSAppleScript(source: PlayPauseScript) {
    scriptObject.executeAndReturnError(nil)
}

**编辑:**以下是目前的问题所在。根据建议,我将此添加到我的info.plist中,现在Spotify AppleScript一致工作(当通过NSAppleScript调用时):

<key>NSAppleEventsUsageDescription</key> 
<string>...this is why I need permission...</string>

看来是我的问题(现在)只是使用系统事件的AppleScripts。尽管确保我的应用程序和osascript都被允许控制我的计算机(通过安全与隐私〉隐私〉可访问性),我现在得到同样的错误使用NEAppleScriptosascript时为(1002)。还允许我的应用控制系统事件(security & privacy〉privacy〉automation). osascript错误打印到Xcode的控制台,我使用下面的代码(在按钮的@IBAction中)发现了NEAppleScript的错误代码:

let script =
"""
try
    tell application "System Events"
        keystroke "c" using {command down}
    end tell
on error errMsg number errorNumber
    display dialog "An unknown error occurred:  " & errorNumber as text
end try
"""

if let scriptObject = NSAppleScript(source: script) {
    scriptObject.executeAndReturnError(nil)
}

上面的代码导致对话框中出现以下内容:An unknown error occurred: 1002
当我的应用运行时,它确实会提示我给予它控制系统事件,我一直都是这么做的。我的应用不是沙盒的。我相信NSAppleScriptoascript都曾为我工作过一次,但当我再次运行应用时就停止工作了(尽管我没有对代码做任何修改,但我几乎是肯定的)。
我不知道这是否是信息,但我唯一的其他线索可能是,我一直必须检查和取消检查脚本编辑器的权限在security & privacy > privacy > accessibility,让它运行这些AppleScript,因为它告诉我,脚本编辑器是不允许发送击键。

pgky5nke

pgky5nke1#

Security & Privacy -> Privacy tab -> Accessibility

添加/usr/bin/操作系统脚本
注意:您可能还需要添加您的终端(在我的情况下是iTerm)

chy5wohz

chy5wohz2#

修复osascript 1002 permission issue.
进入安全和隐私-〉隐私选项卡-〉辅助功能-〉添加osascript(/usr/bin/osascript)
或使用NSAppleScript

tvokkenx

tvokkenx3#

这是你需要考虑的几件事,不仅仅是对你的问题的真实的回答。如果你想要更多的细节,我很乐意根据要求编辑它们。(另外,我会用objective-C写代码示例,因为我还在快速学习)
首先,如果你要在你的应用程序中做很多脚本,那么切换到Scripting Bridge可能是值得的。Scripting Bridge是一个用于apple脚本化其他应用程序的可可接口,所以(借用我在其他地方找到的一个例子)如果你想在iTunes中获得当前曲目的名称,你可以这样做:

iTuneApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
currentTrack = iTunes.currentTrack.name;

如果你想要Spotify的特定代码,我必须安装该应用程序;请告诉我。
第二,如果你想进行击键操作,你应该研究一下Quartz Event Services,QES允许你创建、发送和捕获输入事件,所以如果你想发送一个C,你可以这样做:

// '8' is the key code for 'c'
comCDownEvent = CGEventCreateKeyboardEvent(nil, 8, true); 
CGEventSetFlags(comCDownEvent, kCGEventFlagMaskCommand);
comCUpEvent = CGEventCreateKeyboardEvent(nil, 8, false); 
CGEventSetFlags(comCUpEvent, kCGEventFlagMaskCommand);
CGEventPostToPSN(targetAppProcessSerialNumber, comCDownEvent);
CGEventPostToPSN(targetAppProcessSerialNumber, comCUpEvent);

你不能从沙盒应用程序中运行这些代码,但是我认为你无论如何都会遇到这个问题。
这些方法的主要优点是避免了上下文切换:这一切都是在可可中完成的,因此您不需要调用shell或创建AppleScript环境,并且避免了所有涉及的转换问题。

e7arh2l6

e7arh2l64#

我做了一个AppleScript,抛出了这个错误,并通过在macOS 13.2.1(Ventura)上启用隐私与安全,辅助功能中的AEServer来绕过它。
根据this answer
AEServer是Apple事件服务器,用于控制来自其他Mac的Apple事件。
......所以我不确定这样做是否安全......但它对我很有效。

相关问题