AuthorizationExecuteWithPrivileges已弃用

从更新到OSX 10.7 Lion以来,Xcode告诉我, AuthorizationExecuteWithPrivileges已被弃用。

任何人都可以提出一种方法,我的应用程序可以写入一个目录,它没有权限?

我知道这听起来很疯狂,但这实际上是有效的

 NSDictionary *error = [NSDictionary new]; NSString *script = @"do shell script \"whoami > /tmp/me\" with administrator privileges"; NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script]; if ([appleScript executeAndReturnError:&error]) { NSLog(@"success!"); } else { NSLog(@"failure!"); } 

我从Objective C执行一个Applescript。唯一的缺点是你不能获得永久的root权限。 每次运行时都会要求input密码。

事实上, AuthorizationExecuteWithPrivileges()已经被弃用了很长一段时间,直到最近头文件已经赶上了这个事实。

您可以创build一个特权辅助工具作为您的应用程序的一部分。 您可以使用ServiceManagement.frameworkSMJobBless()函数将helper部署到系统launchd上下文中:然后,当您需要执行特权任务时,您只需发出特权帮助程序即可完成此项工作。

有一点隐藏的复杂性,因为在SMJobBless()认为它们应该一起使用之前,应用程序和助手都必须声明另一个的签名标识,并且您需要让链接器编写帮助工具Info.plist文件放入二进制文件中。 这一切都覆盖了苹果的文档 ,苹果也提供了一个示例项目 。

我写了一个使用SMJobBless()来部署其特权助手的示例应用程序 。

基于user950473的一个很好的发现,我已经实现了他/她的发现作为一种方法; 以为我会分享的代码,以防万一它有帮助。

 - (BOOL) runProcessAsAdministrator:(NSString*)scriptPath withArguments:(NSArray *)arguments output:(NSString **)output errorDescription:(NSString **)errorDescription { NSString * allArgs = [arguments componentsJoinedByString:@" "]; NSString * fullScript = [NSString stringWithFormat:@"'%@' %@", scriptPath, allArgs]; NSDictionary *errorInfo = [NSDictionary new]; NSString *script = [NSString stringWithFormat:@"do shell script \"%@\" with administrator privileges", fullScript]; NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:script]; NSAppleEventDescriptor * eventResult = [appleScript executeAndReturnError:&errorInfo]; // Check errorInfo if (! eventResult) { // Describe common errors *errorDescription = nil; if ([errorInfo valueForKey:NSAppleScriptErrorNumber]) { NSNumber * errorNumber = (NSNumber *)[errorInfo valueForKey:NSAppleScriptErrorNumber]; if ([errorNumber intValue] == -128) *errorDescription = @"The administrator password is required to do this."; } // Set error message from provided message if (*errorDescription == nil) { if ([errorInfo valueForKey:NSAppleScriptErrorMessage]) *errorDescription = (NSString *)[errorInfo valueForKey:NSAppleScriptErrorMessage]; } return NO; } else { // Set output to the AppleScript's output *output = [eventResult stringValue]; return YES; } } 

用法示例:

  NSString * output = nil; NSString * processErrorDescription = nil; BOOL success = [self runProcessAsAdministrator:@"/usr/bin/id" withArguments:[NSArray arrayWithObjects:@"-un", nil] output:&output errorDescription:&processErrorDescription]; if (!success) // Process failed to run { // ...look at errorDescription } else { // ...process output } 

这是非常有点hacky,但恕我直言,是一个令人满意的解决scheme。

AuthorizationExecuteWithPrivileges确实被弃用
幸运的是,还有一种新的推荐方式。

从10.6开始,有新的API,build议安装一个辅助工具来执行特权操作。 苹果提供了一个清晰演示如何pipe理它的代码示例 。

确保你看看他们的readme.txt,因为与其他代码示例相反,除了下载项目并运行它之外还有更多的事情要做。

从SMJobBless示例介绍

SMJobBless演示如何安全地安装执行特权操作的帮助工具,以及如何将该工具与调用它的应用程序相关联。

从Snow Leopard开始,这是在Mac OS X上pipe理特权升级的首选方法, 应该使用而不是BetterAuthorizationSample这样的早期方法,或直接调用AuthorizationExecuteWithPrivileges

SMJobBless使用在Mac OS X v10.6 Snow Leopard中引入的ServiceManagement.framework。

来源: 苹果SMJobBless代码示例