2010-06-10 5 views
27

먼저 비슷한 질문을했지만 답변은 아직까지 도움이되지 않았습니다. 모두 다음 옵션 중 하나를 권장합니다.실행중인 프로세스의 이름 검색

특정 프로세스가 실행 중인지 확인해야하는 사용자 응용 프로그램이 있습니다. 여기에이 과정에 대해 무엇을 알고 :

  • 이름
  • 그것은가 이미 실행해야 (root)
  • 사용자, 그것은
  • 부모 프로세스가 있어야합니다 의미 LaunchDaemon, 이후 launchd (pid 1)

나는 이것을 얻기 위해 여러 가지 방법을 시도했지만 지금까지 아무 것도 시도하지 못했습니다. 다음은 내가 시도한 것입니다.

  1. ps을 실행하고 출력을 구문 분석합니다. 이 방법은 효과가 있지만 속도가 느립니다 (fork/exec은 비쌉니다). 가능한 한 빨리이 기능을 사용하고 싶습니다.

  2. GetBSDProcessList 기능 listed here을 사용하십시오. 이것은 또한 작동하지만 프로세스 이름을 검색하는 방법 (각 kinfo_proc 구조에서 kp_proc.p_comm에 액세스)에는 결함이 있습니다.

    pid_t pids[1024]; 
    int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); 
    proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));  
    for (int i = 0; i < numberOfProcesses; ++i) { 
        if (pids[i] == 0) { continue; } 
        char name[1024]; 
        proc_name(pids[i], name, sizeof(name)); 
        printf("Found process: %s\n", name); 
    }

    이 작품 :

    #define MAXCOMLEN 16 //defined in param.h 
    struct extern_proc { //defined in proc.h 
        ...snip... 
        char p_comm[MAXCOMLEN+1]; 
        ...snip... 
    };
  3. 프로세스 정보를 검색 libProc.h 사용 : 결과 char*kp_proc 구조의 정의에서 볼 수있는 프로세스 이름의 처음 16 개 문자가 포함 단점은 GetBSDProcessList입니다. 프로세스 이름의 첫 번째 부분 만 반환됩니다.

    ProcessSerialNumber psn; 
    psn.lowLongOfPSN = kNoProcess; 
    psn.highLongOfPSN = 0; 
    while (GetNextProcess(&psn) == noErr) { 
        CFStringRef procName = NULL; 
        if (CopyProcessName(&psn, &procName) == noErr) { 
        NSLog(@"Found process: %@", (NSString *)procName); 
        } 
        CFRelease(procName); 
    }

    이 작동하지 않습니다 탄소의 ProcessManager function가 사용

  4. . WindowServer (또는 그와 비슷한 것)에 등록 된 프로세스 만 반환합니다. 즉, 현재 사용자에 대해서만 UI가있는 앱만 반환합니다.

  5. -[NSWorkspace launchedApplications]은 10.5와 호환되어야하므로 사용할 수 없습니다. 또한 현재 사용자의 Dock에 나타나는 응용 프로그램에 대한 정보 만 반환합니다.

나는이 과정을 (ps이 그것을 할 수 있기 때문에) 실행의 이름을 검색 을 있다고 알고 있지만 질문은 "나는 분기 및 ps을 exec'ing없이 그것을 할 수 있습니까?".

제안 사항?

편집

더 많은 연구를하고 후에, 나는이 작업을 수행 할 수있는 방법을 찾을 수있었습니다. 나는 this C file in a python module을 언급 한 this SO question을 발견했다. 이것은 sysctl 호출에서 KERN_PROCARGS 값을 사용하는 데 정말 유용했습니다.

그러나 파이썬 모듈 코드는 소스에서 ps, which I found here으로 파생 된 것으로 보입니다. ps 어떻게 든 실행중인 모든 프로세스의 실행 경로를 얻을 수 있지만 최선의 노력은 이 작업을 수행하지 못했습니다. print.cgetproclline이라는 마법의 기능이있는 것 같습니다.하지만 내 자신의 명령 줄 도구에서 동일한 코드를 실행하면 내 프로세스 이외의 다른 프로세스에서 실행 가능한 프로세스를 검색 할 수 없습니다.

저는 계속 실험 할 것입니다. 그러나 더 확실한 증거가 없으면 @ drawnonward의 대답이 지금까지 가장 정확합니다.


EDIT (나중에 오랜 시간이) 대답 pointed to by Quinn Taylor-

덕분에, 나는 작동하는 무언가를 발견했습니다. 각 프로세스의 실행 경로를 얻은 다음 실제 프로세스 이름을 얻기 위해 마지막 경로 구성 요소를 가져올 수 있습니다.

#import <sys/proc_info.h> 
#import <libproc.h> 

int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); 
pid_t pids[numberOfProcesses]; 
bzero(pids, sizeof(pids)); 
proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids)); 
for (int i = 0; i < numberOfProcesses; ++i) { 
    if (pids[i] == 0) { continue; } 
    char pathBuffer[PROC_PIDPATHINFO_MAXSIZE]; 
    bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE); 
    proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer)); 
    if (strlen(pathBuffer) > 0) { 
     printf("path: %s\n", pathBuffer); 
    } 
} 
+0

프로세스 이름이 특정 길이에서 잘리지 만 전체 목록을 반환하는'sysctl()'호출을 생각해 보입니다. – Wevah

+1

@Wevah 맞습니다. 'sysctl()'은 완전한리스트를 리턴하지만 이름은 16 문자로 잘립니다. 목록의 항목 # 2입니다. :) –

+0

아, 나는 언급 된'sysctl()'을 보지 못했습니다 (링크도 클릭하지 않았습니다). DOUBLEDeong NSUIElement가 1로 설정된 응용 프로그램이 있는데, 응용 프로그램 이름을 얻고 있습니다. ProcessManager 함수를 사용하고 있습니다. (이 정보를 사용할 수 있으므로 질문을 올리십시오.) – Wevah

답변

관련 문제