这是使用 NSAppleScript 将参数传递到 AppleScript 处理程序的正确方法:
// load/compile AppleScript
NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
@"on joinText(a, b)\n"
@" return a & b\n"
@"end addTo"];
NSString *arg1 = @"Hello ";
NSString *arg2 = @"World!";
// pack positional parameters
NSAppleEventDescriptor *params = [NSAppleEventDescriptor listDescriptor];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg1] atIndex: 1];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg2] atIndex: 2];
// build Apple event to invoke user-defined handler in script
NSAppleEventDescriptor *eventDesc = [NSAppleEventDescriptor appleEventWithEventClass: 'ascr'
eventID: 'psbr'
targetDescriptor: [NSAppleEventDescriptor nullDescriptor]
returnID: 0
transactionID: 0];
[eventDesc setDescriptor: params forKeyword: '----'];
[eventDesc setDescriptor: [NSAppleEventDescriptor descriptorWithString: @"joinText"] forKeyword: 'snam'];
// invoke handler
NSDictionary *errorInfo = nil;
NSAppleEventDescriptor *resultDesc = [scpt executeAppleEvent: eventDesc error: &errorInfo];
if (resultDesc)
NSLog(@"Result: %@\n", [resultDesc stringValue]);
else
NSLog(@"Error: %@\n", errorInfo);
这避免了即时编译和编译 AS 脚本的需要 - 正如您的原始 ObjC 代码所展示的那样,由于清理不足,这是在您的程序中引入错误和安全漏洞的丰富机会。
...
这是在 AppleScript 中组装 shell 脚本字符串的正确方法:
do shell script ("chown -R " & quoted form of username & " " & quoted form of filepath)
AppleScript 的do shell script命令不提供传递参数的安全机制(它在许多其他方面也存在缺陷),但 AS 字符串具有quoted form至少返回适合连接到 shell 脚本字符串的带引号和转义版本的文本的属性.
...
当然,通过do shell scriptAppleScript 调用 shell 只是为了chmod以升级的权限运行,这本身并不是一个小问题,尽管这主要是 Apple 的错,因为它没有提供简单的官方 API 来执行此操作(例如,通过添加“以管理员权限运行”选项到NSUserScriptTask)。
Apple 确实提供了一个示例项目SMJobBless,它展示了如何使用服务管理框架和 launchd 添加和运行特权进程。但这是一个足够复杂的解决方案,很多人会(有意或无意地)偷工减料或完全做错事,这反而违背了首先提供安全做事方式的意义。但是您需要与 Apple 合作。