【发布时间】:2011-01-31 20:50:24
【问题描述】:
Mac 上是否有可用的 Carbon/Cocoa/C API 可用于枚举进程?我在 Windows 上寻找类似 @987654321@ 的东西。
我的目标是从代码中检查进程是否正在运行(按名称)。
谢谢!
【问题讨论】:
标签: cocoa macos unix macos-carbon
Mac 上是否有可用的 Carbon/Cocoa/C API 可用于枚举进程?我在 Windows 上寻找类似 @987654321@ 的东西。
我的目标是从代码中检查进程是否正在运行(按名称)。
谢谢!
【问题讨论】:
标签: cocoa macos unix macos-carbon
这里有一些具体的实现和细节,注意 proc->kp_proc.p_comm 有一个字符长度限制,这就是我实现 infoForPID: 的原因
可可:
[NSWorkspace 启动应用程序](10.2+ ,在 10.7 中已弃用,非常有限的进程列表) [NSWorkspace runningApplications](10.6+,较少限制的进程列表,但仍不包括守护进程)
碳:
- (NSArray*)getCarbonProcessList
{
NSMutableArray *ret = [NSMutableArray arrayWithCapacity:1];
ProcessSerialNumber psn = { kNoProcess, kNoProcess };
while (GetNextProcess(&psn) == noErr) {
CFDictionaryRef cfDict = ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask);
if (cfDict) {
NSDictionary *dict = (NSDictionary *)cfDict;
[ret addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"%@",[dict objectForKey:(id)kCFBundleNameKey]],@"pname",
[NSString stringWithFormat:@"%@",[dict objectForKey:@"pid"]],@"pid",
[NSString stringWithFormat:@"%d",(uid_t)getuid()],@"uid",
nil]];
CFRelease(cfDict);
}
}
return ret;
}
C:(见Technical Q&A QA1123 Getting List of All Processes on Mac OS X)
- (NSArray*)getBSDProcessList
{
NSMutableArray *ret = [NSMutableArray arrayWithCapacity:1];
kinfo_proc *mylist;
size_t mycount = 0;
mylist = (kinfo_proc *)malloc(sizeof(kinfo_proc));
GetBSDProcessList(&mylist, &mycount);
int k;
for(k = 0; k < mycount; k++) {
kinfo_proc *proc = NULL;
proc = &mylist[k];
NSString *fullName = [[self infoForPID:proc->kp_proc.p_pid] objectForKey:(id)kCFBundleNameKey];
if (fullName == nil) fullName = [NSString stringWithFormat:@"%s",proc->kp_proc.p_comm];
[ret addObject:[NSDictionary dictionaryWithObjectsAndKeys:
fullName,@"pname",
[NSString stringWithFormat:@"%d",proc->kp_proc.p_pid],@"pid",
[NSString stringWithFormat:@"%d",proc->kp_eproc.e_ucred.cr_uid],@"uid",
nil]];
}
free(mylist);
return ret;
}
- (NSDictionary *)infoForPID:(pid_t)pid
{
NSDictionary *ret = nil;
ProcessSerialNumber psn = { kNoProcess, kNoProcess };
if (GetProcessForPID(pid, &psn) == noErr) {
CFDictionaryRef cfDict = ProcessInformationCopyDictionary(&psn,kProcessDictionaryIncludeAllInformationMask);
ret = [NSDictionary dictionaryWithDictionary:(NSDictionary *)cfDict];
CFRelease(cfDict);
}
return ret;
}
【讨论】:
TechZen 说:截至 2013 年 12 月,流程管理器已完全弃用。
啊,我刚刚找到Process Manager reference
看起来 GetNextProcess 和 GetProcessInfo 有助于找出正在运行的内容。正如 Dave 所建议的,如果您正在寻找守护进程而不仅仅是 Carbon/Cocoa 进程,则可以使用GetBSDProcessList。
【讨论】:
GetBSDProcessList 比您自己迭代流程管理器要快得多。
有几种方法可以做到这一点:
-[NSWorkspace launchedApplications]。NSTask 分叉另一个进程(如 ps 或 top 或其他),阅读结果,然后搜索自己(或通过 grep 或其他方式进行管道传输)。GetBSDProcessList 函数:http://developer.apple.com/legacy/mac/library/#qa/qa2001/qa1123.html(我过去曾成功使用过此功能)【讨论】:
在NSRunningApplicationClass的概述中,它说:
NSRunningApplication 是一个为应用程序的单个实例操作和提供信息的类。仅跟踪用户应用程序;这并不提供有关系统上每个进程的信息。
和
要访问所有正在运行的应用程序的列表,请使用NSWorkspace 中的 runningApplications 方法。
【讨论】:
迟到了,但如果您确实需要一个强大的解决方案来检查任何进程是否正在运行(包括 BSD 进程),您可以执行以下操作:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/types.h>
int main(int argc, const char* argv[]) {
pid_t pid = atoi(argv[2]);
// This MIB array will get passed to sysctl()
// See man 3 sysctl for details
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
struct kinfo_proc result;
size_t oldp_len = sizeof(result);
// sysctl() refuses to fill the buffer if the PID does not exist,
// so the only way to detect failure is to set all fields to 0 upfront
memset(&result, 0, sizeof(struct kinfo_proc));
if (sysctl(name, 4, &result, &oldp_len, NULL, 0) < 0) {
perror("sysctl");
return 1;
}
// SZOMB means a zombie process, one that is still visible but is not running anymore
if (result.kp_proc.p_pid > 0 && result.kp_proc.p_stat != SZOMB) {
printf("Process is running.\n");
} else {
printf("Process is NOT running.\n");
}
return 0;
}
请注意,上面的代码是我的一个私有库的修改版本,未经测试。但是,它应该清楚 API 的使用方式,并在 macOS 10.14.5 上成功运行。
【讨论】:
您可以使用自 macOS 10.15 起可用的 EndPointSecurity.framework。更多信息请参考Writing a Process Monitor with Apple's Endpoint Security Framework
【讨论】: