Package location by identifier

I want to create a package from an arbitrary bundle identifier
e.g. com.apple.iokit.IOStorageFamily

It is not an unreasonable thing to assume that package identifiers are unique, however the obvious code does not work:

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

This code only works for packages that you have already downloaded.
(hello, chicken and egg problem), and in fact you have to know a little more than you would like to know about the identifier
before you can do anything. For the above ID style
I am preparing the last component and converting it to /System/Library/Extensions/IOStorageFamily.kext
which I then upload along the way.

Is this a modern level or is there a more general way?

+6
cocoa macos
source share
6 answers

More recently, Andrew Myrick answered a similar question on the darwin-dev mailing list:

KextManagerCreateURLForBundleIdentifier() in <IOKit/kext/KextManager.h> can be used, although I believe that it only works for kexts that are either 1) loaded, or 2) in / S / L / E /. Here is the Snow 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 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); 

Note that prior to Snow Leopard, this could only work for kexts in / S / L / E; An API exists, but there was no headerdoc describing its behavior.

For me, this worked very well on Mac OS X 10.5.

+3
source share

Use this

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

I don't think Mac OS X stores a global database of all package identifiers everywhere.

As already noted, you can find the application quite simply with NSWorkspace.

In addition, since you used kext for your example, Leopard (10.5) has a tool called "kextfind" that you can run to search for kexts in the "Extensions" folder (kexts will not be found in other places, except you specify the tool in these other places). Kextfind has many options - see the man page for details - but to find kext by package id, you can do this:

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

We currently do not have a C-level API to search for kexts by package identifier.

As for hacking the path from the last component of the bundle identifier: don't do this. There doesnโ€™t require anything for the wrapper name to match the last component of the package identifier, and I saw kexts (not to mention other packages) where the two do not match.

+4
source share

If what you are looking for is definitely kext, then you can look up the information dictionary for each package in the / S / L / Es / folder until you find yours. There is no search for a bundle by identifier, except for applications (where LaunchServices does), and downloaded packages, as you already found.

0
source share

To answer this question, I think you really need to know: "Why are you looking for package identifiers this way?" If there are always kexts, you can search in some pretty reasonable places, if they are applications, you can use LS, I do not see the case in which you would like to do both, so I do not see the need for a common way to do this.

It should be noted that you can have multiple instances of identical package identifiers on the volume.

0
source share

For completeness, I should mention that you can search for all packages (not just KEXT) with a given package identifier using kMDItemCFBundleIdentifier Spotlight / metadata; Of course, you should be prepared to process where there is more than one (usually they should have different versions).

0
source share

All Articles