どのように私は、Mac OS Xでのストレージデバイスのアイコンを取得することができますか?

StackOverflow https://stackoverflow.com/questions/580002

  •  06-09-2019
  •  | 
  •  

質問

私はIOServiceGetMatchingServicesを使用して、私のデバイスを発見し、このようなプロパティの辞書を持っています

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

私はアイコンの情報を抽出することができ、その辞書から:

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

これら二つが私に与えて、この(例として):

com.apple.iokit.IOStorageFamily   (Bundle identifier)
Internal.icns                     (Resource File)

私はこの方法を使用してアイコンを抽出しようとした。

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

しかしbundleWithIcon nilです。

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

私はこれを行うことができますか?

、私は何とかbundleWithIdentifierでそれを読み込むことができるようにバンドルをロードするために持っていると思います

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

役に立ちましたか?

解決 2

つい最近アンドリュー・マイリックは、同様の質問ダーウィン-devメーリングリストでます:

  

KextManagerCreateURLForBundleIdentifier()   <IOKit/kext/KextManager.h>であってもよく、   使用の、私はそれを信じているものののみ作品   1)ロードされているいずれかのkextのために、   又は2)に/ S / L / Eの/。ここでは雪があります   ヒョウ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のkextのために働くこと。インクルード   APIは存在していたが、ノーがありました   その動作を説明headerdocます。

は、私にとってこれは、Mac OS X 10.5上で本当によく働いています。

他のヒント

あなたはNSWorkspaceを使用することができます。
初期画像は32×32であるが、他のサイズの表現を有し、それに応じてスケーリングされます

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSImage * icon = [ws iconForFile:@"/Volumes/Whatever"];
NSLog(@"%@", [icon representations]); // see what sizes the icon has
icon.size = NSMakeSize(512, 512);

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

「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 <

  

これら二つが私に与えて、この(例として):

     

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

     

私はこの方法を使用してアイコンを抽出しようとした。

     

NSBundle * bundleWithIcon = [NSBundle bundleWithIdentifier:入札]。     NSStringの*あるIconPath = [bundleWithIcon pathForResource:RFILE ofType:なし];

     

しかしbundleWithIcon nilです。

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

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

scroll top