SMJobBless - 关于何时要求输入管理员密码的文档

时间:2011-09-29 20:47:47

标签: macos cocoa launchd

我似乎无法找到任何关于此的文档,所以希望有人可以通过Apple的示例SMJobBless代码确认我看到的行为。

我的印象是,如果检测到需要安装新版本的帮助工具,它只会要求输入管理员密码。

然而,这种印象显然是不正确的。

我在10.6下看到的行为是,如果我是第一次启动应用程序,它会要求输入密码。如果我几乎立即启动,它就不会。但是,如果我等待足够长的时间,它将再次要求输入密码。在所有这些过程中,辅助工具不会改变。

任何人都可以指出将此定义为正确行为的文档吗?

1 个答案:

答案 0 :(得分:13)

如果有人有兴趣,这(可能)结果是一个错误,一个已经提交。 rdar:// 10280469

系统当前的工作方式是每次都要求输入管理员密码,无论SMJobBless功能是否需要安装帮助工具。如果不需要安装帮助工具(例如,它已经安装并且与应用程序包中的版本具有相同的版本),则该错误(可能)不应该发出管理员密码请求。

所以,这意味着需要在调用SMJobBless和SMJobBless之前确定是否需要安装辅助工具,如果已经知道需要安装辅助工具的话

在我的情况下,我只需要检查工具是否已安装(SMJobCopyDictionary处理此工具),如果安装了该工具,则其版本是否比我的应用程序包中的工具版本旧。

检查工具是否已安装以及版本是什么的一些(不完整)代码如下所示。

还有另一种方法可以对助手工具进行版本检查,帮助工具接收对其版本的请求,并发送回版本。就个人而言,我喜欢下面的方法,但是想提一下这个替代方案,因为它可能是某些情况下的最佳途径。

NSDictionary* installedHelperJobData;

installedHelperJobData  = (NSDictionary*)SMJobCopyDictionary( kSMDomainSystemLaunchd, (CFStringRef)@"com.apple.bsd.SMJobBlessHelper" );

NSString*       installedPath           = [[installedHelperJobData objectForKey:@"ProgramArguments"] objectAtIndex:0];
NSURL*          installedPathURL        = [NSURL fileURLWithPath:installedPath];

NSDictionary*   installedInfoPlist      = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)installedPathURL );
NSString*       installedBundleVersion  = [installedInfoPlist objectForKey:@"CFBundleVersion"];
NSInteger       installedVersion        = [installedBundleVersion integerValue];

NSLog( @"installedVersion: %ld", (long)installedVersion );

NSBundle*       appBundle       = [NSBundle mainBundle];
NSURL*          appBundleURL    = [appBundle bundleURL];

NSURL*          currentHelperToolURL    = [appBundleURL URLByAppendingPathComponent:@"Contents/Library/LaunchServices/com.apple.bsd.SMJobBlessHelper"];
NSDictionary*   currentInfoPlist        = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)currentHelperToolURL );
NSString*       currentBundleVersion    = [currentInfoPlist objectForKey:@"CFBundleVersion"];
NSInteger       currentVersion          = [currentBundleVersion integerValue];

NSLog( @"currentVersion: %ld", (long)currentVersion );