How to write a list of all running processes for OSX and save them as a file in Xcode / Cocoa?

I want to write 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'm not sure how to do this. Please help! Thanks!

+4
source share
2 answers

As explained in QA1123 , “process” means several different things on a Mac (and this changes over time).

A “process” at the Cocoa level (or Carbon, or once during Classic) is basically what the end user perceives as a process: application, fba, launchit, etc. A “process” at the BSD level is what is perceived as a Unix-processed system administrator, like a process: something that appears in ps . A high-level process may have several BSD processes; on the contrary, it was also possible (under the classics); You can also have BSD processes that do not have a high-level process. and etc.

If you want a high-level definition, forget that the QA method -[NSWorkspace runningApplications] that you mentioned returns exactly what you want: an array with an object for each such application, and these objects have all the necessary information. How you save them in a file depends on what information you want to receive for each of them, in what format you want to save this information, etc. Here is a complete sample application that will save the URL of each application, one per line, to the "./appslist" file:

 #include <Cocoa/Cocoa.h> int main(int argc, char *argv[]) { NSString *output = [NSString string]; for (NSRunningApplication *app in [[NSWorkspace sharedWorkspace] runningApplications]) { output = [output stringByAppendingFormat:@"%@\n", [[app bundleURL] absoluteString]]; } [output writeToFile:@"./appslist" atomically:YES encoding:NSUTF8StringEncoding error:NULL]; return 0; } 

If you want a low-level definition, the code in this QA is still accurate. Or you can just exec (or system or NSTask ) ps .

In any case, here is a sample that (with the code from this QA) prints the pid of each running process in a local file named "./bsdlist":

 int main(int argc, char *argv[]) { kinfo_proc *procs; size_t count; int err = GetBSDProcessList(&procs, &count); if (err) return err; FILE *f = fopen("./bsdlist", "w"); for (size_t i=0; i!=count; ++i) { fprintf(f, "%d\n", procs[i].kp_proc.p_pid); } fclose(f); free(procs); } 

If you like the idea of ps scripts as mentioned above, there are several ways to do this.

The DDTask library mentioned in Dominik's answer looks like the easiest way to do this. If you want to use NSTask directly, installing NSPipe for stdout requires a bit more code, etc. There is a nice generic CocoaDev there (this is an ls script, not a ps , but the ideas are all the same.)

Or you can go down to a lower level. You can explicitly specify fork / exec and pass the results through stdout, but the popen function is designed to carry all this, and it is much easier to use. The GNU C Programming Tutorial shows how to popen ps -A and pass it to grep init ; the first half is all you need.

Whichever way you set off, the problem is that you are going to return a mess of lines that you should parse. The best thing to do is pass different ps flags to get what you really want. If all you need is command lines, ps -ax -ocommand= will not give you anything but one command line per line - there is no title bar for skips, columns for parsing, etc.

If you are concerned about performance: QA says that "exec'ing ps will require parsing the output of the tool and will not use system resources as efficiently as in Listing 1". And it is true; formatting sysctl output into strings so that they can be piped and parsed again, this is an extra job that takes some processor time. But if you do it millions of times, I doubt it uses enough to make a difference. The best approach (to this and in most cases) is to first write simpler code and check if it is enough; if so, you are done.

+10
source

yip, to get a high-level request in the workspace, as shown by abarnet to get "all" processes go to the lower level and execute ps through NSTask and read the answer through NSPipe.

there’s an example code with an apple. or use DDTask (the wrapper I wrote) the github repository

 NSString *exe = @"/bin/ps"; NSArray *args = @[@"-ax"]; NSString *res = [DDTask runTaskWithToolPath:exe andArguments:args andErrorHandler:nil]; [res writeToFile:@"./appslist" atomically:YES encoding:NSUTF8StringEncoding error:NULL]; 
+1
source

Source: https://habr.com/ru/post/1434296/


All Articles