5

OSXで実行中のすべてのプロセスのリストをキャプチャし、それらをXcode/Cocoaにファイルとして保存したいと考えています。私はこれをグーグルで検索しました、そして私が見つけたのは:

[myWorkspace runningApplications];

そして、私はこれを行う方法がわかりません。助けてください!ありがとうございました!

4

2 に答える 2

13

QA1123で説明されているように、「プロセス」は Mac では複数の異なるものを意味します (そして、時間の経過とともに変化します)。

Cocoa (または Carbon、または昔ながらのクラシック) のレベルでの「プロセス」は、基本的にエンドユーザーがプロセスとして考えるものです: アプリ、fba、launchitem など。 BSD は、Unix の訓練を受けたシステム管理者がプロセスとして考えているものですps。高レベルのプロセスは、複数の BSD プロセスを持つことができます。その逆も可能でした (Classic で)。高レベルのプロセスを持たない BSD プロセスを使用することもできます。等

高レベルの定義が必要な場合は、QA を忘れて-[NSWorkspace runningApplications]ください。あなたが言及したメソッドは、必要なものを正確に返します。そのようなアプリごとにオブジェクトを含む配列であり、それらのオブジェクトには必要なすべての情報が含まれています。それらをファイルに保存する方法は、各アプリについて必要な情報、その情報を保存する形式などによって異なります。次に示すのは、各アプリの URL を 1 行に 1 つずつファイルに保存する完全なサンプル アプリです。 "./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または、 (またはsystemまたはNSTask)だけでもかまいませんps

とにかく、これは (その 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's answer で言及されているDDTaskライブラリは、これを行う最も簡単な方法のようです。直接使用したい場合は、stdout などのNSTask設定にもう少しコードが必要です。優れた一般的なCocoaDevがあります (スクリプトではなくスクリプトですが、アイデアはすべて同じです)。NSPipelsps

または、より低いレベルにドロップダウンすることもできます。明示的にfork/execして stdout を介して結果を渡すこともできますが、popen関数はそのすべてをラップするように設計されており、はるかに使いやすくなっています。GNU C プログラミング チュートリアルpopen ps -Aでは、パイプする方法を示していgrep initます。必要なのは前半だけです。

どちらにしても問題は、解析しなければならない混乱した文字列が返されることです。最善の方法は、さまざまなフラグを渡してps、実際に必要なものだけを取得することです。コマンド ラインだけps -ax -ocommand=が必要な場合は、1 行に 1 つのコマンド ラインのみが表示されます。ヘッダー行をスキップしたり、列を解析したりする必要はありません。

効率が心配な場合: QA は、「ps を実行するにはツールの出力を解析する必要があり、リスト 1 ほど効率的にシステム リソースを使用しない」と述べています。これは本当です。出力を文字列にフォーマットsysctlしてパイプ経由で渡し、再度解析することは CPU 時間を消費する余分な作業です。しかし、これを何百万回も実行しない限り、違いを生むのに十分な量を使用しているとは思えません。(これとほとんどの場合) 最善の方法は、最初に単純なコードを記述し、それが十分に高速かどうかをテストすることです。そうであれば、完了です。

于 2012-09-14T23:00:47.233 に答える
1

yipを使用して、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];
于 2012-09-14T23:13:21.267 に答える