问题
Does anyone know of a good way to find (in the filesystem) every app with a given bundle identifier? NSWorkspace
and Launch Services let you look for an app by bundle identifier, but only return a single result. I suspect Spotlight (NSMetadataQuery
) might help, but I'm a bit unclear on its API, so I'm not sure if there's an appropriate key.
There's the command-line lsregister
tool (inside LaunchServices.framework), which can be told to (re)register everything on the system and then dump a report on everything it knows about. Relying on that seems less than ideal, since it's undocumented and parsing its output could be a pain.
(Background: I'm building an app for game modding, and want to provide UI for quickly choosing from a short list of supported games rather than requiring the user to dig through the whole filesystem in an Open panel. However, I expect it's quite likely for a user to have multiple copies of a game installed: release and beta, extra copies for modding, etc.)
回答1:
This question was asked in 2012 concerning OS X Lion 10.7. As of OS X Yosemite 10.10 the answer is:
LSCopyApplicationURLsForBundleIdentifier
Summary:
Given a bundle identifier (such as com.apple.finder), find all URLs to the corresponding application.
Discussion:
Returns zero or more URLs to applications that have the specified bundle identifier.
回答2:
You want the kMDItemCFBundleIdentifier
Spotlight/metadata key.
pierre$39> mdfind "kMDItemCFBundleIdentifier == 'org.videolan.vlc'"
/Applications/VLC.app
/Applications/vlc-0.8.6c/VLC.app
From there it should just be a matter of making the right calls to the file metadata APIs (pick your poison, Carbon or Cocoa). Interestingly enough, this key is not very well documented: it is not in File Metadata Attributes Reference, though it is in MDItem Reference.
Once again, it goes to show that game modding tools raise use cases few other kind of apps raise, and that sometimes aren't very well served by Apple… </soapbox>
Addendum: once you have your list, in my opinion the best way to present it to the user would be to list the version (kMDItemVersion
) of each item you found; you might also show the path, but the version is likely going to be the most useful thing to the user (after all, he likely keeps different instances in order to have specific versions).
回答3:
Another alternative is to use LSCopyApplicationURLsForURL to find all copies of all applications that handle a specific URL scheme. This does require the application to define a URL scheme however.
For example, you could find all email applications that handle the 'mailto' scheme, even if there are multiple versions of the same app on the system.
This is the only way I know to get all applications, instead of what the system considers the 'default' or 'preferred' application returned with other calls.
来源:https://stackoverflow.com/questions/8841043/how-to-find-multiple-apps-with-same-bundle-identifier