简体   繁体   中英

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

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.

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 (eg 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.

Nope - running ps is your best bet. Standard process info interfaces aren't supported on OS X (noop versions were provided in OS X 10.4, but removed thereafter) and the private interfaces are likely to change between OS X revisions.

If you're willing to lock yourself into a single OS X version, all the source is available, for example for ps or libproc ; you'll also need to run as root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM