3

IOServiceGetMatchingServices次のようなプロパティ ディクショナリを使用して取得したデバイスを見つけました。

kernResult = IORegistryEntryCreateCFProperties(nextMedia,
                    (CFMutableDictionaryRef *)&props,
                                              kCFAllocatorDefault, 0);

その辞書から、アイコンの情報を抽出できます。

NSString *bId = [props valueForKeyPath:@"IOMediaIcon.CFBundleIdentifier"];
NSString *rFile = [props valueForKeyPath:@"IOMediaIcon.IOBundleResourceFile"];

これら2つは私にこれを与えます(例として):

com.apple.iokit.IOStorageFamily (バンドル識別子)
Internal.icns (リソース ファイル)

この方法を使用してアイコンを抽出しようとしました:

NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId];
NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];

しかしbundleWithIconですnil

これはアイコンを取得する正しい方法ですか?

でロードできるようにするには、どうにかしてバンドルをロードする必要があると思いますbundleWithIdentifier。どうすればこれを行うことができますか?

PS:(私が思うに)同じことを尋ねようとする別の質問がありますが、これが正しい方法であるかどうかではなく、バンドルのみを要求します。

4

5 に答える 5

7

NSWorkspace を使用できます。
初期画像は 32x32 ですが、他のサイズの表現があり、それに応じてスケーリングされます

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSImage * icon = [ws iconForFile:@"/Volumes/Whatever"];
NSLog(@"%@", [icon representations]); // see what sizes the icon has
icon.size = NSMakeSize(512, 512);
于 2009-02-25T09:08:45.483 に答える
2

つい最近、 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-02-24T12:29:05.637 に答える
1

これはあなたを助けるかもしれません。(またはそうでないかもしれません)...

「ioreg」コマンドをいじっていると、あなたの質問を思い出させるものに出くわしたので、投稿します。

次のコマンドを発行してみてください。

ioreg -c IOMedia -x

これは、次のような出力の大きな混乱をもたらします。

  |     +-o IOBlockStorageDriver  <class IOBlockStorageDriver, registered, matched, active, busy 0, retain 7>
  |       +-o Apple read/write Media  <class IOMedia, registered, matched, active, busy 0, retain 9>
  |         | {
  |         |   "Removable" = Yes
  |         |   "BSD Unit" = 0x4
  |         |   "IOBusyInterest" = "IOCommand is not serializable"
  |         |   "BSD Minor" = 0xc
  |         |   "Ejectable" = Yes
  |   |         |   "BSD Name" = "disk4"
  |         |   "Leaf" = No
  |         |   "IOMediaIcon" = {"CFBundleIdentifier"="com.apple.iokit.IOStorageFamily","IOBundleResourceFile"="Removable.icns"}
  |         |   "Preferred Block Size" = 0x200
  |         |   "Whole" = Yes
  |         |   "Open" = Yes
  |         |   "Size" = 0x100000
  |         |   "Writable" = Yes
  |         |   "Content" = "Apple_partition_scheme"
  |         |   "IOGeneralInterest" = "IOCommand is not serializable"
  |         |   "Content Hint" = ""
  |         | }         |   "BSD Major" = 0xe

以上のことから、「IOMedia」に一致する io レジストリ ツリーをトラバースすると、「IOMediaIcon」というキーを持つエントリを含むプロパティ ディクショナリを取得できると思われます (したがって、ここではやみくもに調査することをお勧めします)。バンドル識別子とリソース ファイル名を通知するコレクション。

これが簡単だとは言いません...しかし、必要なすべてのサンプルコードについてはFireWire SDKを調べてください...いずれにせよ、事前に入力されたパスをハードコーディングするよりもおそらく「優れている」でしょう(将来のOSでは消える可能性があります)リリース)。

|K<

于 2009-05-12T15:44:45.137 に答える
0

カスタムアイコンのないボリュームは、ここへのパスをハードコーディングしたOSの汎用アイコンの1つで表示されます。カスタムアイコンのあるボリュームは、そのアイコンをファイルシステムに保存します。マウントされていない場合は、それを見つけることが完全にあなたの仕事になります。

于 2009-10-14T13:27:45.410 に答える
0

これら2つは私にこれを与えます(例として):

com.apple.iokit.IOStorageFamily (バンドル識別子) Internal.icns (リソースファイル)

この方法を使用してアイコンを抽出しようとしました:

NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId]; NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];

しかしbundleWithIconですnil

bundleWithIdentifier:その識別子を持つバンドルの NSBundle インスタンスをすでに作成している必要があります。以前に作成されたインスタンスのみを検索します。したがって、ファイル システムでバンドルを見つけて、パス名でインスタンス化する必要があります。幸いなことに、あなたはそれについての質問へのリンクをすでに持っているようです。

于 2009-02-24T01:58:12.923 に答える