按标识符定位包

时间:2008-10-13 12:23:03

标签: cocoa macos

我想从任意包标识符中创建一个包 例如com.apple.iokit.IOStorageFamily

因为捆绑ID应该是这样做,这不是一件不合理的事情 是唯一的,但明显的代码不起作用:

NSString* bID = @"com.apple.iokit.IOStorageFamily";
NSBundle* bundle = [NSBundle bundleWithIdentifier:bID];

此代码仅适用于您已加载的捆绑包 (你好,鸡肉和鸡蛋问题),事实上,你有 比你想知道的标识符更多一点 在你做任何事之前。对于上述风格的身份
我把最后的组件弄出来并将其转换成
/System/Library/Extensions/IOStorageFamily.kext
然后我按路径加载。

这是最先进的技术还是有更普遍的方式?

6 个答案:

答案 0 :(得分:9)

使用此

NSString *path = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.TextEdit"];

答案 1 :(得分:4)

我认为Mac OS X不会在任何地方保留所有捆绑ID的全局数据库。

如上所述,您可以使用NSWorkspace以非常简单的方式找到应用程序。

此外,由于您在示例中使用了kext,因此在Leopard(10.5)上有一个名为“kextfind”的工具,您可以运行该工具来搜索系统Exensions文件夹中的kexts(除非在其他地方使用kexts,否则将无法找到你将工具指向其他地方)。 kextfind有很多选项 - 有关详细信息,请参阅手册页 - 但要按包ID查找kext,您可以执行此操作:

kextfind -bundle-id com.apple.iokit.IOStorageFamily

我们目前没有用于通过捆绑ID查找kexts的C级API。

至于黑客攻击捆绑包ID的最后一个组件的路径:不要这样做。没有什么要求包装器名称与包ID的最后一个组件匹配,我已经看到了kexts(更不用说其他包),两者不匹配。

答案 2 :(得分:3)

刚刚在darwin-dev邮件列表上Andrew Myrick answered a similar question

  

KextManagerCreateURLForBundleIdentifier()   在<IOKit/kext/KextManager.h>可能是   使用,虽然我相信它只有作用   对于1)加载的kexts,   或2)在/ S / L / E /。这是雪   Leopard headerdoc:

/*!
 * @function KextManagerCreateURLForBundleIdentifier
 * @abstract Create a URL locating a kext with a given bundle identifier.
 *
 * @param    allocator
 *           The allocator to use to allocate memory for the new object.
 *           Pass <code>NULL</code> or <code>kCFAllocatorDefault</code>
 *           to use the current default allocator.
 * @param    kextIdentifier
 *           The bundle identifier to look up.
 *
 * @result
 * A CFURLRef locating a kext with the requested bundle identifier.
 * Returns <code>NULL</code> if the kext cannot be found, or on error.
 *
 * @discussion
 * Kexts are looked up first by whether they are loaded, second by version.
 * Specifically, if <code>kextIdentifier</code> identifies a kext
 * that is currently loaded,
 * the returned URL will locate that kext if it's still present on disk.
 * If the requested kext is not loaded,
 * or if its bundle is not at the location it was originally loaded from,
 * the returned URL will locate the latest version of the desired kext,
 * if one can be found within the system extensions folder.
 * If no version of the kext can be found, <code>NULL</code> is returned.
 */
CFURLRef KextManagerCreateURLForBundleIdentifier(
    CFAllocatorRef allocator,
    CFStringRef    kextIdentifier);
     

请注意,在Snow Leopard之前,它   可能仅适用于/ S / L / E中的kexts;该   API存在,但没有   headerdoc描述了它的行为。

对我而言,这在Mac OS X 10.5上运行得非常好。

答案 3 :(得分:0)

如果您正在寻找的肯定是一个kext,那么您可以查看/ S / L / Es /文件夹中每个包的信息字典,直到找到您的。除了应用程序(LaunchServices将执行此操作)之外,没有搜索标识符的捆绑包,并且已经找到已加载的捆绑包。

答案 4 :(得分:0)

为了回答这个问题,我想真的需要知道“你为什么要用这种方式查看包标识符?”如果总有kexts你可以在一些相当合理的地方搜索,如果它们是你可以使用LS的应用程序,我没有看到你想要两者都做的情况,所以我认为不需要常用的方法。

应该注意,卷上可以有多个相同的包标识符实例。

答案 5 :(得分:0)

为了完整起见,我应该提到您可以使用kMDItemCFBundleIdentifier Spotlight /元数据键搜索具有给定包标识符的所有包(不仅仅是KEXT);当然,你必须准备好处理不止一个(通常他们应该有不同的版本)。