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) には、システムの Exensions フォルダーで kext を検索するために実行できる「kextfind」というツールがあります (他の場所にある kext は、それらの他の場所でツール)。kextfind には多くのオプションがあります -- 詳細については man ページを参照してください -- しかし、バンドル ID で kext を見つけるには、次のようにします:

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

現在、バンドル ID で kext を検索するための C レベル API はありません。

バンドル ID の最後のコンポーネントからパスをハッキングすることに関しては、そうしないでください。ラッパー名がバンドル ID の最後のコンポーネントと一致する必要はありません。2 つが一致しない kext (他のバンドルは言うまでもありません) を見たことがあります。

于 2008-11-04T00:41:58.033 に答える
3

つい最近、 Andrew Myrick がdarwin-dev メーリング リストで同様の質問に答えました。

KextManagerCreateURLForBundleIdentifier() in<IOKit/kext/KextManager.h>は役に立つかもしれませんが、1) ロードされているか、2) /S/L/E/ にある kext に対してのみ機能すると思います。Snow Leopard のヘッダードキュメントは次のとおりです。

/*!
 * @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 は存在しましたが、その動作を説明するヘッダードキュメントはありませんでした。

私の場合、これは Mac OS X 10.5 で非常にうまく機能しました。

于 2009-10-17T20:40:37.920 に答える
0

探しているものが明らかに kext である場合は、/S/L/Es/ フォルダー内の各バンドルの情報ディクショナリを調べて、自分のものを見つけることができます。アプリケーション (LaunchServices が実行する場所) を除いて、識別子によるバンドルの検索はなく、既に見つけたようにバンドルをロードします。

于 2008-10-13T22:04:16.420 に答える
0

この質問に答えるには、「なぜバンドル識別子をこのように探しているのか」を知る必要があると思います。かなり合理的な場所で検索できるkextが常にある場合、それらがLSを使用できるアプリである場合、両方を実行したい場合はないと思います。一般的なやり方。

ボリューム上に同一のバンドル ID のインスタンスを複数持つことができることに注意してください。

于 2008-11-04T00:51:09.387 に答える
0

kMDItemCFBundleIdentifier完全を期すために、 Spotlight/metadata キーを使用して、特定のバンドル ID を持つすべてのバンドル (KEXT だけでなく) を検索できることに言及する必要があります。もちろん、複数あることを処理する準備ができている必要があります (通常、それらは異なるバージョンを持つ必要があります)。

于 2012-04-08T16:15:33.070 に答える