0

How can I retrieve this info? Given a NSRunningApplication instance, I need to know who launched it. Activity Monitor shows this info.

user732274
  • 1,069
  • 1
  • 12
  • 28

3 Answers3

2

From the documentation on NSRunningApplication: Only user applications are tracked; this does not provide information about every process on the system.

I.e. it won't give you all the processes on the system.

The closest you can do is grab the runningApplications from NSWorkspace. But that'll be an incomplete list.

Alternatively, you can dive down to the same APIs the system uses in Activity Monitor. But that'll be painful. Or you could launch ps auxwww from NSTask and parse the output, also painful.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • I already use runningApplications from NSWorkspace, but it returns an array of NSRunningApplications, so we come back to my initial question. Parsing the output of ps is a quite smart tip, though... – user732274 Jan 11 '14 at 19:25
  • @user732274 The issue, though, is that `runningApplications` from `NSWorkspace` is very incomplete; it only returns a small subset of the processes that are running as the user that is running the code that called `runningApplications`. – bbum Jan 11 '14 at 19:43
  • Does he need all the processes? The question isn't very clear on that. – Wevah Jan 11 '14 at 19:45
  • Done all these suggestions, and I approve it is painful. Also it is incorrect that you only get running apps for the calling user. If you use runningApplications as root - you'll get all the instances of apps launched by any logged-in user. – Motti Shneor Mar 09 '23 at 07:12
2

If you just need the name of the user who launched an instance of NSRunningApplication, here's a category method that should do it:

#import <libproc.h>
#import <pwd.h>

@implementation NSRunningApplication (UserName)

- (NSString *)foo_userName {
    pid_t pid = [self processIdentifier];
    struct proc_bsdshortinfo info;
    proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof(info));
    struct passwd *passwd = getpwuid(info.pbsi_uid);
    return [NSString stringWithUTF8String:passwd->pw_name];
}

@end
Wevah
  • 28,182
  • 7
  • 83
  • 72
  • Oops, doesn't return an error, looks like; it returns a size instead. Fixing. – Wevah Jan 11 '14 at 19:42
  • 1
    Your method should be prefixed since it is in a category on a framework class. Also, since `NSRunningApplication` only represents apps run by the same user that is running the above code and, then, only a subset of the apps currently running, this code doesn't really do much of interest overall (but could certainly be used by OP if they grab the list of PIDs first). – bbum Jan 11 '14 at 19:45
  • If all he cares about is "running applications", it should be fine; he's not very clear about whether he wants all processes or just applcations. :/ – Wevah Jan 11 '14 at 19:46
  • (Used "foo_" in my edit because I can't come up with a better one right now.) – Wevah Jan 11 '14 at 19:48
  • It is not true that NSRunningApplication only represents apps run by the user executing this code - I'm executing "runningApplicationsForBundleID" as root - and see all instances of the app launched by all logged-in users. – Motti Shneor Mar 09 '23 at 07:10
0

NSRunningApplication class will only give you instances of apps run by the CURRENT USER. If multiple users are concurrently logged in to the Mac, each running their own Applications, NSRunningApplication will NOT provide the list of running apps for all the logged in users. Only the apps of the calling user.

That said, the OP’s question translates to “what is my user name” because any NSRunningApplication instance will be owned and run by that user,

An important side note - NSRunningApplication only returns the main processes of bundled apps. It will NOT provide sub processes (XPC services,login items, daemons agents, command-line tools etc). Many apps today delegate most of their work to one of these subprocesses and will not be captured.

Motti Shneor
  • 2,095
  • 1
  • 18
  • 24