简体   繁体   English

如何捕获OSX的所有正在运行的进程列表并将它们保存为Xcode / Cocoa中的文件?

[英]How do I capture a list of all running processes for OSX and save them as a file in Xcode / Cocoa?

I am wanting to capture a list of all running processes for OSX and save them as a file in Xcode / Cocoa. 我想捕获OSX的所有正在运行的进程的列表,并将它们保存为Xcode / Cocoa中的文件。 I googled this and all I found was: 我用谷歌搜索了这一切,我发现的是:

[myWorkspace runningApplications]; [myWorkspace runningApplications];

And I am not sure how to do this. 我不知道该怎么做。 Please Help! 请帮忙! Thank you! 谢谢!

As explained in QA1123 , "process" means multiple different things on a Mac (and that changes over time). 正如QA1123中所解释的那样 ,“进程”在Mac上意味着多种不同的东西(随着时间的推移而变化)。

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 . Cocoa级别的“过程”(或者说是Carbon,或曾经的经典)基本上是最终用户认为的过程:app,fba,launchitem等等。 BSD是受过Unix训练的系统管理员所认为的一个过程:在ps东西。 A high-level process can have multiple BSD processes; 高级进程可以有多个BSD进程; the other way around used to be possible too (under Classic); 另一种方式也是可能的(在Classic下); you can also have BSD processes that have no high-level process; 你也可以拥有没有高级过程的BSD流程; 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. 如果你想要高级定义,忘记QA,你提到的方法-[NSWorkspace runningApplications]完全返回你想要的东西:一个带有每个这样的app的对象的数组,那些对象拥有你想要的所有信息。 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": 如何将它们保存在文件中取决于您想要的每个信息,您希望保存该信息的格式等。这是一个完整的示例应用程序,它将每个应用程序的URL(每行一个)保存到文件中叫做“./appslist”:

#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 the low-level definition, the code in that QA is still accurate. 如果您想要低级别定义,那么QA中的代码仍然是准确的。 Or you could just exec (or system or NSTask ) ps . 或者你可以只exec (或systemNSTaskps

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": 无论如何,这是一个示例(使用该QA的代码)将每个正在运行的进程的pid打印到名为“./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 scripting ps , as mentioned above, there are a number of ways to do this. 如果你喜欢脚本ps的想法,如上所述,有很多方法可以做到这一点。

The DDTask library mentioned in Dominik's answer looks like the easiest way to do this. Dominik的答案中提到的DDTask库看起来是最简单的方法。 If you want to use NSTask directly, it takes a bit more code to set up an NSPipe for stdout, etc. There's a good general CocoaDev (it's scripting ls rather than ps , but the ideas are all the same.) 如果你想直接使用NSTask ,需要更多的代码来为stdout等设置NSPipe 。有一个很好的通用CocoaDev (它的脚本ls而不是ps ,但想法都是一样的。)

Or you could drop down to a lower level. 或者你可以下降到较低的水平。 You could explicitly fork / exec and pass the results through stdout, but the popen function is designed to wrap all of that up, and it's a lot easier to use. 您可以显式fork / exec并通过stdout传递结果,但popen函数旨在将所有这些包装起来,并且它更容易使用。 The GNU C Programming Tutorial shows how to popen ps -A and pipe it to grep init ; GNU C编程教程展示了如何popen ps -A并将其传递给grep 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. 最好的办法是将不同的标志传递给ps以便只获得你真正想要的东西。 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. 如果你想要的只是命令行, ps -ax -ocommand=将只给你一个,每行一个命令行 - 没有要跳过的标题行,没有要拆分的列等等。

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." 如果你担心效率:QA说“执行ps将需要解析工具的输出,并且不会像清单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. sysctl输出格式化为字符串只是为了将它们传递给管道并再次解析它们是额外的工作,需要花费一些 CPU时间。 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. 如果是的话,你已经完成了。

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. 如abarnet所示,获取高级查询工作空间以使“所有”进程更低级并通过NSTask执行ps并通过NSPipe读取响应。

there's sample code by apple .. or use DDTask (a wrapper I wrote) github repository 有苹果的示例代码..或使用DDTask(我写的包装) github存储库

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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在xcode中运行打包的Shell脚本文件? (可可) - How do I run a packaged shell script file in xcode? (Cocoa) 如何在xcode可可项目中创建一个打开的文件对话框? - How do I create an open file dialog in a xcode cocoa project? 如何从1 xcode项目中保存所有构建设置并在其他xcode项目中使用它们? - How can I save all my build settings from 1 xcode project and use them on other xcode projects? Xcode 6.1:在所有OSX Swift项目中突然没有这样的模块&#39;cocoa&#39; - Xcode 6.1: no such module 'cocoa' suddenly in all OSX Swift projects 如何在 Xcode 中使用 iOS\\Cocoa Touch\\Objective-C 类模板创建文件 - How do I create a file with the iOS\Cocoa Touch\Objective-C class template in Xcode 同一Xcode项目文件中的Cocoa(OSX)和CocoaTouch(iPhone)组件? - Cocoa (OSX) and CocoaTouch (iPhone) components in the same Xcode project file? Xcode可可OSX NSTextfield查询 - Xcode cocoa osx NSTextfield query 在可可中,如何使用特定的UTI保存文本 - In cocoa, how do I save text with a particular UTI 如何在 OSX Ventura 13.1 中打开 Xcode 13.4.1? - How do I open Xcode 13.4.1 in OSX Ventura 13.1? 如何在 Mac OSX 的 Xcode 中启用 C++17? - How do I enable C++17 in Xcode for Mac OSX?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM