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.