在Mac应用程序中获得写入\Library\ColorSync\Profiles\文件的权限

11

我需要从我的Mac应用程序将文件写入 \Library\ColorSync\Profiles。因此,该应用程序需要管理员权限才能读写文件夹。是否可能在应用程序内部实现相同的功能?任何帮助都将不胜感激。

我可以使用以下代码片段弹出权限对话框

 NSSavePanel *tvarNSSavePanelObj    = [NSSavePanel savePanel];
[tvarNSSavePanelObj setDirectoryURL:[NSURL URLWithString:@"/Library/ColorSync/Profiles"]];

__block NSString *filePathexn  = nil;

[tvarNSSavePanelObj beginSheetModalForWindow:[NSApplication sharedApplication].mainWindow completionHandler:^(NSInteger tvarInt) {
    if(tvarInt == NSModalResponseOK){
        NSURL* tvarUrl = [tvarNSSavePanelObj URL];
        NSLog(@"doSaveAs filename = %@",[tvarUrl path]);
        NSString *filePath = [tvarUrl path];
        filePathexn = [filePath stringByAppendingPathExtension:@"rtf"];
        OSStatus status;
        if(![[NSFileManager defaultManager]isWritableFileAtPath:filePath]){
            NSLog(@"Not Writable at path");
            AuthorizationRef authRef;
            AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
            AuthorizationRights rights = {1, &right};
            status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagPreAuthorize, &authRef);
            AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize;
            status = AuthorizationCopyRights(authRef, &rights, kAuthorizationEmptyEnvironment, authFlags, NULL);
        }
       BOOL status1 = [[NSFileManager defaultManager]createFileAtPath:filePathexn contents:nil attributes:nil];

    } else if(tvarInt == NSModalResponseCancel) {
        return;
    } else {
        NSLog(@"doSave As tvarInt not equal 1 or zero = %3ld",(long)tvarInt);
        return;
    }
}];

我需要了解如何进行文件写入。文件仍未写入路径。是否需要指定任何工具名称?可以使用SMJobless()实现吗?请给出解决方案的建议!


您没有提供关键信息。 - El Tomato
@ElTomato 我做了一些编辑。现在你能否请评论一下? - Govind
你的应用程序面向哪些用户?如果你打算通过Mac App Store分发你的应用程序,你将不被允许提示用户进行管理员身份验证。 - El Tomato
@ElTomato 它没有通过 Mac 应用商店进行分发。有没有其他方法可以实现呢? - Govind
你的状态是AuthorizationCreate,然后变成了AuthorizationCopyRights,这似乎不对。我认为在确认身份验证成功之后才应该授予权限。其次,在调用NSSavePanel之前,难道不需要启动身份验证吗? - El Tomato
@ElTomato 我已经成功进行了授权复制,但仍无法将文件写入指定路径。 - Govind
3个回答

2
我可以提供两种方法。一种方法快速但已被弃用。第二种方法现代化,但需要一些编程和阅读文档:
  1. 您需要编写bash脚本来执行所需的操作,并使用类似于STPrivilegedTask的权限授予执行它。
  2. 编写特权辅助工具,在第一次使用root权限访问时安装,您将能够执行任何特权操作如何编写特权辅助工具

你好,能否提供更多细节?我能在我的项目中使用STPrivillaged Task吗?现在它能正常工作吗?如果我编写一个特权助手工具,我能够为我的应用程序获取root权限吗?你有任何示例吗?请给予建议。 - Govind
这取决于你需要实现什么。STPrivilegedTask 可以为你工作,但你的代码会有少量关于停用的警告。使用 STPrivilegedTask 的缺点是每次需要特权操作时,你都需要从用户那里请求密码。我认为这不太友好。因此,我的建议是,如果这个操作很少用,并且你没有时间研究助手工具概念,那么就使用 STPrivilegedTask。否则,请使用特权助手工具。 - toohtik
但请注意,如果您想要管理员权限而不使用AuthorizationExecuteWithPrivileges,则只需要特权帮助工具。 - toohtik
我的要求是使用fwrite()函数生成一个文件到/Library/ColorSync/文件夹中。为此,我是否需要编写一个工具? - Govind
完全不需要。但是特权助手工具对于应用程序来说很好,因为它看起来对用户有用,可以避免多次输入密码。 - toohtik

2
如果你想保存一个ColorSync配置文件,ColorSyncProfileInstall 将为你完成所有繁重的工作,例如提示用户进行许可和身份验证。️
同时,还需要包含代码签名 COLORSYNC_PROFILE_INSTALL_ENTITLEMENT 权限:
<key>com.apple.developer.ColorSync.profile.install</key>
<true/>

文档中提到的符号的说明可以在ColorSyncProfile.h头文件中找到,这里为了方便部分内容已经复制。
CSEXTERN bool ColorSyncProfileInstall(ColorSyncProfileRef profile, CFStringRef domain, CFStringRef subpath, CFErrorRef* error);
   /*
    * profile   - profile to be installed
    * domain    - either kColorSyncProfileComputerDomain or kColorSyncProfileUserDomain.
    *             kColorSyncProfileComputerDomain is for sharing the profiles (from /Library/ColorSync/Profiles).
    *             kColorSyncProfileUserDomain is for user custom profiles (installed under home directory, i.e. in 
    *             ~/Library/ColorSync/Profiles.
    *             NULL is the same as kColorSyncProfileUserDomain.
    * subpath   - CFString created from the file system representation of the path of the file to contain the installed
    *             profile. The last component of the path is interpreted as a file name if it ends with the extension ".icc".
    *             Otherwise, the subpath is interpreted as the directory path and file name will be created from the 
    *             profile description tag, appended with the ".icc" extension.
    * error     - (optional) pointer to the error which will be returned in case of failure.
    *
    *             bool value true is returned if success or false in case of error.
    */

2

我在这里发布另一个解决方案。我阅读了应用程序分发指南。指南中提到,授权API不建议用于在应用商店之外分发的应用程序。 不管怎样,这个解决方案对我有用,它是一个小小的黑客技巧,我不知道。我尝试从应用程序中运行苹果脚本,该脚本赋予文件夹完整的权限(chmod 777 path),在完成任务后将其设置回以前的权限设置。

- (void)runapplescript{
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = NULL;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
                               @"do shell script \"chmod 777 /Library/ColorSync/Profiles\" with administrator privileges"];
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];

}

与其使用chmod,更推荐使用mv。将项目保存在某个临时位置,然后移动到/Library/文件夹中。 - Govind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接