6

Is there a way to get all installed applications for the current user in cocoa?

NSArray *runningApps = [[NSWorkspace sharedWorkspace] launchedApplications];

The above gives me currently running applications but for my app I need to list all installed applications. I need the application key (e.g. com.apple.appname) so system_profiler will does not work.

Kamran224
  • 1,584
  • 7
  • 20
  • 33
  • http://stackoverflow.com/questions/3444326/list-all-applications-output-as-text-file – Anoop Vaidya Jan 13 '14 at 12:59
  • Here is the solution : [how to get all installed applicaitons(StackOverFlow) ][1] [1]: http://stackoverflow.com/questions/31700347/how-to-get-all-installed-applications-with-objective-c-in-osx/31701135#31701135 – Vikas Bansal Jul 30 '15 at 06:46
  • 1
    @VikasBansal the key difference between the solution you point to and the one I provided is that mine will find applications on the entire machine (if you remove the scope line) and will only return actual applications, not other files in the `/Applications` directory. – gaige Sep 25 '15 at 10:10

1 Answers1

10

For OSX, the key library for gathering information about launchable applications is Launch Services (see Apple's Launch Services Programming Guide), which will give you the information about an application such as bundle id, file types that it accepts, etc.

For actually locating all executables on the machine, you're going to want to use Spotlight in one form or the other (either the API or by calling out to mdfind).

Example of using the command line version:

mdfind "kMDItemContentType == 'com.apple.application-bundle'"

will return a list of all application paths.

Using a similar term in the spotlight API will result in an appropriate list, from which you can then either open the main bundle using NSBundle or use Launch Services to retrieve information about the app.

I don't have time to do a thorough test of this, but the basic code would be:

NSMetadataQuery *query = [[NSMetadataQuery alloc] init];        
[query setSearchScopes: @[@"/Applications"]];  // if you want to isolate to Applications
NSPredicate *pred = [NSPredicate predicateWithFormat:@"kMDItemContentType == 'com.apple.application-bundle'"];

// Register for NSMetadataQueryDidFinishGatheringNotification here because you need that to
// know when the query has completed

[query setPredicate:pred];
[query startQuery]; 

(Revised to use @John's localization-independent query instead of my original)

gaige
  • 17,263
  • 6
  • 57
  • 68
  • 1
    Thanks. For anyone wondering, you can use the following for the notificaiton: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryFinish:) name:NSMetadataQueryDidFinishGatheringNotification object:nil]; – Kamran224 Jan 15 '14 at 01:02
  • 4
    Careful, kMDItemKind is localized. You might want to use "kMDItemContentType == 'com.apple.application-bundle'" instead. – John Mar 02 '16 at 20:09
  • @John I think you can write an answer. It will save our (not native english speaker) time – wangqi060934 Mar 16 '19 at 09:20
  • @wangqi060934 updated answer after testing John’s suggested improvement – gaige Mar 16 '19 at 14:22