I am wanting to capture a list of all running processes for OSX and save them as a file in Xcode / Cocoa. I googled this and all I found was:
[myWorkspace runningApplications];
And I am not sure how to do this. Please Help! Thank you!
I am wanting to capture a list of all running processes for OSX and save them as a file in Xcode / Cocoa. I googled this and all I found was:
[myWorkspace runningApplications];
And I am not sure how to do this. Please Help! Thank you!
yip to get high-level query the workspace as shown by abarnet to get 'all' processes go lower-level and execute ps via an NSTask and read the response via a NSPipe.
there's sample code by apple .. or use DDTask (a wrapper I wrote) github repository
As explained in QA1123, "process" means multiple different things on a Mac (and that changes over time).
A "process" at the level of Cocoa (or Carbon, or once upon a time Classic) is basically what an end-user thinks of as a process: an app, fba, launchitem, etc. A "process" at the level of BSD is what a Unix-trained sysadmin thinks of as a process: something that shows up in
ps
. A high-level process can have multiple BSD processes; the other way around used to be possible too (under Classic); you can also have BSD processes that have no high-level process; etc.If you want the high-level definition, forget that QA, the method
-[NSWorkspace runningApplications]
that you mentioned returns exactly what you want: an array with an object for each such app, and those objects have all the info you want. How you save them in a file depends on what information you want about each one, what format you want to save that information in, etc. Here's a complete sample app that will save the URL of each app, one per line, to a file called "./appslist":If you want the low-level definition, the code in that QA is still accurate. Or you could just
exec
(orsystem
orNSTask
)ps
.Anyway, here's a sample that (with the code from that QA) prints the pid of each running process to a local file called "./bsdlist":
If you like the idea of scripting
ps
, as mentioned above, there are a number of ways to do this.The
DDTask
library mentioned in Dominik's answer looks like the easiest way to do this. If you want to useNSTask
directly, it takes a bit more code to set up anNSPipe
for stdout, etc. There's a good general CocoaDev (it's scriptingls
rather thanps
, but the ideas are all the same.)Or you could drop down to a lower level. You could explicitly
fork
/exec
and pass the results through stdout, but thepopen
function is designed to wrap all of that up, and it's a lot easier to use. The GNU C Programming Tutorial shows how topopen
ps -A
and pipe it togrep init
; the first half of this is all you need.Whichever way you go, the problem is that you're going to get back a mess of strings you have to parse. The best thing to do is pass different flags to
ps
to only get what you actually want. If all you want is the command lines,ps -ax -ocommand=
will give you nothing but that, one command line per line—no header line to skip, no columns to parse apart, etc.If you're worried about efficiency: The QA says "exec'ing ps will require parsing the tool's output and will not use system resources as efficiently as Listing 1." And this is true; formatting the
sysctl
output into strings just to pass them over a pipe and parse them again is extra work that has to take some CPU time. But unless you're doing this millions of times, I doubt it uses enough to make a difference. The best approach (to this, and most cases) is to write the simpler code first and test whether it's fast enough; if it is, you're done.