如何在OS X服务菜单中自动激活项目

时间:2010-10-04 22:54:34

标签: objective-c cocoa macos

我需要在服务菜单中默认启用我创建的服务。

我为我的OS X应用程序创建了一项服务(在Snow Leopard上运行)。我已经像这样配置了Info.plist:

<key>NSServices</key>
<array>
    <dict>
        <key>NSSendTypes</key>
        <array>
            <string>NSStringPboardType</string>
        </array>
        <key>NSMessage</key>
        <string>dropService</string>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Drop Service</string>
        </dict>
        <key>NSPortName</key>
        <string>MyApp</string>
    </dict>
</array>

到目前为止,我遵循以下所述的其他步骤:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/SysServices/introduction.html,一切似乎都正常。

我跑了命令:

/System/Library/CoreServices/pbs

现在我的服务显示在“系统偏好设置 - &gt;键盘 - &gt;键盘快捷键 - &gt;服务”下。所以系统知道它。但它不会显示在服务菜单中,除非我手动激活它。

当我尝试调试服务时,收到此消息:

/Applications/TextEdit.app/Contents/MacOS/TextEdit -NSDebugServices com.myapp.MyApp
Drop Service (com.myapp.MyApp) is disabled in the services menu and disabled in the context menu, by the standard Services policy.

我不知道“标准服务政策”是什么,我在Apple开发者网站上找不到任何对此错误的引用。

我认为自动启用服务项目是不可能的,但我已经确认某些应用程序会这样做(比如来自文化代码的东西)所以我知道它可以完成。

有什么想法吗?

3 个答案:

答案 0 :(得分:12)

默认情况下启用服务而不破解任何系统plist的正确方法是编辑自己的plist。具体来说,在每个服务字典中添加NSRequiredContext密钥。此信息来自this mailing list post(取自this answer on a similar question)。

至于您需要为该密钥提供的值the documentation will fill you in

答案 1 :(得分:11)

只需在Info.plist中添加一个NSRequiredContext键,其中包含空白字典作为其对象。以下是它的外观:

<key>NSRequiredContext</key>
<dict>
</dict>

答案 2 :(得分:2)

我不知道有任何公共API可以做到这一点,但我找到了解决它的方法。所有已激活服务的列表都保存在

~/Library/Preferences/pbs.plist

您只需添加一个条目并重置pbs即可。我正在使用以下代码段:

NSString*pbsPlistPath=[@"~/Library/Preferences/pbs.plist" stringByExpandingTildeInPath];
NSMutableDictionary*dict=[NSPropertyListSerialization 
                                  propertyListFromData:[NSData dataWithContentsOfFile:pbsPlistPath]
                                    mutabilityOption:NSPropertyListMutableContainers
                                                format:NULL
                                      errorDescription:NULL];
NSMutableDictionary*status=[dict objectForKey:@"NSServicesStatus"];
if(!status){
    status=[NSMutableDictionary dictionary];
    [dict setObject:status forKey:@"NSServicesStatus"];
}
if(status){
    NSMutableDictionary*m=[NSMutableDictionary dictionary];
    [m setObject:[NSNumber numberWithBool:YES] forKey:@"enabled_context_menu"];
    [m setObject:[NSNumber numberWithBool:YES] forKey:@"enabled_services_menu"];
    [status setObject:m
               forKey:@"com.my.app - Drop Service - dropService"];
}
NSData* data=[NSPropertyListSerialization dataWithPropertyList:dict
                                                        format:NSPropertyListBinaryFormat_v1_0
                                                       options:0
                                                         error:NULL];
[data writeToFile:pbsPlistPath atomically:YES];
system("/System/Library/CoreServices/pbs -flush");
system("/System/Library/CoreServices/pbs -flush_userdefs");