OSXで実行中のすべてのプロセスのリストをキャプチャし、それらをXcode/Cocoaにファイルとして保存したいと考えています。私はこれをグーグルで検索しました、そして私が見つけたのは:
[myWorkspace runningApplications];
そして、私はこれを行う方法がわかりません。助けてください!ありがとうございました!
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があります (スクリプトではなくスクリプトですが、アイデアはすべて同じです)。NSPipe
ls
ps
または、より低いレベルにドロップダウンすることもできます。明示的にfork
/exec
して stdout を介して結果を渡すこともできますが、popen
関数はそのすべてをラップするように設計されており、はるかに使いやすくなっています。GNU C プログラミング チュートリアルpopen
ps -A
では、パイプする方法を示していgrep init
ます。必要なのは前半だけです。
どちらにしても問題は、解析しなければならない混乱した文字列が返されることです。最善の方法は、さまざまなフラグを渡してps
、実際に必要なものだけを取得することです。コマンド ラインだけps -ax -ocommand=
が必要な場合は、1 行に 1 つのコマンド ラインのみが表示されます。ヘッダー行をスキップしたり、列を解析したりする必要はありません。
効率が心配な場合: QA は、「ps を実行するにはツールの出力を解析する必要があり、リスト 1 ほど効率的にシステム リソースを使用しない」と述べています。これは本当です。出力を文字列にフォーマットsysctl
してパイプ経由で渡し、再度解析することは、 CPU 時間を消費する余分な作業です。しかし、これを何百万回も実行しない限り、違いを生むのに十分な量を使用しているとは思えません。(これとほとんどの場合) 最善の方法は、最初に単純なコードを記述し、それが十分に高速かどうかをテストすることです。そうであれば、完了です。
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];