6

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

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

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

这段代码只适用于你已经加载的包
(你好,鸡和蛋的问题),事实上,在你做任何事情之前,你必须
比你想知道的标识符多
一点。对于上面的 ID 样式,
我 grep 出最终组件并将其转换为
/System/Library/Extensions/IOStorageFamily.kext
然后通过路径加载。

这是最先进的技术还是有更通用的方法?

4

6 回答 6

9

用这个

NSString *path = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.TextEdit"];
于 2008-10-13T16:35:28.380 回答
5

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

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

此外,由于您在示例中使用了 kext,因此在 Leopard (10.5) 上有一个名为“kextfind”的工具,您可以运行它来搜索系统 Exensions 文件夹中的 kext(除非您指向其他地方的工具)。kextfind 有很多选项——有关详细信息,请参见手册页——但要通过捆绑 ID 查找 kext,您可以这样做:

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

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

至于从捆绑 ID 的最后一个组件中破解路径:不要那样做。没有什么要求包装器名称与包 ID 的最后一个组件匹配,而且我见过 kexts(更不用说其他包),两者不匹配。

于 2008-11-04T00:41:58.033 回答
3

就在最近,Andrew Myrick在 darwin-dev 邮件列表上回答了一个类似的问题:

KextManagerCreateURLForBundleIdentifier() in<IOKit/kext/KextManager.h>可能有用,但我相信它只适用于 1) 已加载或 2) 在 /S/L/E/ 中的 kext。这是雪豹头文件:

/*!
 * @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 中的 kext;API 存在,但没有描述其行为的 headerdoc。

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

于 2009-10-17T20:40:37.920 回答
0

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

于 2008-10-13T22:04:16.420 回答
0

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

应该注意的是,您可以在一个卷上拥有多个相同捆绑标识符的实例。

于 2008-11-04T00:51:09.387 回答
0

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

于 2012-04-08T16:15:33.070 回答