Mac OS X: Getting detailed process information (specifically its launch arguments) for arbitrary running applications using its PID

cocoa, command-line-arguments, objective-c, pid, process

Solution

You could use whatever `ps` uses, though it isn't cocoa based. According to Singh, `ps` is based on kvm and sysctl calls. Pouring over the source, the pertinant calls seem to be `kvm_openfiles`, `kvm_getprocs` and `kvm_getargv`. To get the command line arguments, first call `kvm_openfiles` to get access to the kernel memory space, then use `kvm_getprocs` to get kernel process info, then `kvm_getargv`.

The use of `sysctl` in `ps` seems less relevant to your goal; it's used to get other information, such as the group ID and parent proces ID. The particular sysctl name used is `{CTL_KERN, KERN_PROC, KERN_PROC_which, flags}`, where which specifies a process filter (e.g. `ALL`, `PID`) and flags are arguments for the filter (the details are in the `sysctl` man page).

OS X doesn't have support procfs, but Singh developed a FUSE based version, released under GPLv2. If you bundle it with your application, you'll have to release it under GPLv2 as well. Most of MacFUSE is released under a BSD-style license, so it can be distributed with your app without making it open source (fusefs/fuse_nodehash.c is released under Apple's open source license, but it also allows linking to closed source apps).

The question "Get other process' argv in OS X using C" should be of use, as it has sample code using kvm and sysctl. TN 2050 "Observing Process Lifetimes Without Polling" may also be of use to you.

Problem

I am trying to detect when particular applications are launched. Currently I am using `NSWorkspace`, registering for the "did launch application" notification. I also use the `runningApplications` method to get apps that are currently running when my app starts. For most apps, the name of the app bundle is enough. I have a plist of "known apps" that I cross check with the name of that passed in the notification. This works fine until you come across an app that acts as a proxy for launching another application using command line arguments. Example: The newly released Portal on the Mac doesn't have a dedicated app bundle. Steam can create a shortcut, which serves as nothing more than to launch the `hl2_osx` app with the `-game` argument and `portal` as it's parameter. Since more Source based games are heading to the Mac, I imagine they'll use the same method to launch, effectively running the `hl2_osx` app with the `-game` argument. Is there a nice way to get a list of the arguments (and their parameters) using a Cocoa API? `NSProcessInfo` comes close, offering an `-arguments' method, but only provides information for its own process... `NSRunningApplication` offers the ability to get information about arbitrary apps using a PID, but no command line args... Is there anything that fills the gap between the two? I'm trying not to go down the route of spawning an `NSTask` to run `ps -p [pid]` and parsing the output... I'd prefer something more high level.

Original source

Related problems