You're going to need to use the HIServices framework to achieve what you want to do. Don't worry, it's included by default; just #import <ApplicationServices/ApplicationServices.h>. Then you'll need to get a LaunchServices ProcessSerialNumber for each app and use that to get the information dictionary for those apps. You will want to ignore any apps where the LSUIElement value is non-zero, or the LSBackgroundOnly value is non-zero.
Here's a sample for you:
#import <Cocoa/Cocoa.h>
#import <ApplicationServices/ApplicationServices.h>
@implementation MyAppDelegate
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
NSMutableArray * visibleApps = [NSMutableArray new];
NSMutableArray * hiddenApps = [NSMutableArray new];
NSArray * runningApps = [[NSWorkspace sharedWorkspace] runningApplications];
for ( NSRunningApplication * app in runningApps )
{
ProcessSerialNumber psn;
if ( GetProcessForPID(app.processIdentifier, &psn) != noErr )
{
NSLog(@"Failed to get process serial number for %@!", app.localizedName);
continue;
}
NSDictionary * info = CFBridgingRelease(ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask));
if ( info == nil )
{
NSLog(@"Failed to get process information for %@!", app.localizedName);
continue;
}
if ( [[info objectForKey: @"LSBackgroundOnly"] boolValue] || [[info objectForKey: @"LSUIElement"] boolValue] )
{
// it's not a user-facing app
[hiddenApps addObject: app];
}
else
{
// it's user-facing
[visibleApps addObject: app];
}
}
NSLog(@"User-visible apps: %@", [visibleApps valueForKey: @"localizedName"]);
NSLog(@"Hidden apps: %@", [hiddenApps valueForKey: @"localizedName"]);
}
@end