簡體   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?

我想捕獲OSX的所有正在運行的進程的列表,並將它們保存為Xcode / Cocoa中的文件。 我用谷歌搜索了這一切,我發現的是:

[myWorkspace runningApplications];

我不知道該怎么做。 請幫忙! 謝謝!

正如QA1123中所解釋的那樣 ,“進程”在Mac上意味着多種不同的東西(隨着時間的推移而變化)。

Cocoa級別的“過程”(或者說是Carbon,或曾經的經典)基本上是最終用戶認為的過程:app,fba,launchitem等等。 BSD是受過Unix訓練的系統管理員所認為的一個過程:在ps東西。 高級進程可以有多個BSD進程; 另一種方式也是可能的(在Classic下); 你也可以擁有沒有高級過程的BSD流程; 等等

如果你想要高級定義,忘記QA,你提到的方法-[NSWorkspace runningApplications]完全返回你想要的東西:一個帶有每個這樣的app的對象的數組,那些對象擁有你想要的所有信息。 如何將它們保存在文件中取決於您想要的每個信息,您希望保存該信息的格式等。這是一個完整的示例應用程序,它將每個應用程序的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;
}

如果您想要低級別定義,那么QA中的代碼仍然是准確的。 或者你可以只exec (或systemNSTaskps

無論如何,這是一個示例(使用該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);
}

如果你喜歡腳本ps的想法,如上所述,有很多方法可以做到這一點。

Dominik的答案中提到的DDTask庫看起來是最簡單的方法。 如果你想直接使用NSTask ,需要更多的代碼來為stdout等設置NSPipe 。有一個很好的通用CocoaDev (它的腳本ls而不是ps ,但想法都是一樣的。)

或者你可以下降到較低的水平。 您可以顯式fork / exec並通過stdout傳遞結果,但popen函數旨在將所有這些包裝起來,並且它更容易使用。 GNU C編程教程展示了如何popen ps -A並將其傳遞給grep init ; 這一切的前半部分就是你所需要的。

無論你走哪條路,問題都在於你要找回你需要解析的亂七八糟的字符串。 最好的辦法是將不同的標志傳遞給ps以便只獲得你真正想要的東西。 如果你想要的只是命令行, ps -ax -ocommand=將只給你一個,每行一個命令行 - 沒有要跳過的標題行,沒有要拆分的列等等。

如果你擔心效率:QA說“執行ps將需要解析工具的輸出,並且不會像清單1那樣有效地使用系統資源。” 這是真的; sysctl輸出格式化為字符串只是為了將它們傳遞給管道並再次解析它們是額外的工作,需要花費一些 CPU時間。 但除非你這樣做了數百萬次,否則我懷疑它是否足以產生影響。 最好的方法(對此,大多數情況)是首先編寫更簡單的代碼並測試它是否足夠快; 如果是的話,你已經完成了。

如abarnet所示,獲取高級查詢工作空間以使“所有”進程更低級並通過NSTask執行ps並通過NSPipe讀取響應。

有蘋果的示例代碼..或使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM