我试图使用MacOS X中的"top“命令来确定哪个应用程序正在使用这些资源。当我这么做时:
顶级-stats "pid,命令“
如果进程名太长,命令列将被截断。
如果您查看活动监视器,进程名称将正确显示(全名)+图标。我的问题是:
发布于 2013-01-16 21:56:00
首先,如果您试图以编程方式获取数据,那么驱动top
几乎肯定不是您想要做的事情。
但是,要回答你的直接问题:
如何获得完整的进程名称?
无法控制命令的截断。您可以使用-ncols
参数来设置非交互式输出的输出宽度,但如果top
想要的话,这并不能阻止它截断输出。
有时应用图标显示在进程名旁边,是否有使用objective来做类似的事情?我应该简单地导航到应用程序内容文件夹并抓取icns图像吗?
不是的。您将如何处理具有多个.icns文件的应用程序,例如文档图标?(例如,用iTunes试试。如果选择第一个.icns,就会得到AIFF文档图标;如果选择最后一个,则会得到内部使用最近电视节目的图标。)
正确的方法是为应用程序获取NSBundle
,然后执行如下操作:
NSString *iconFile = [bundle objectForInfoDictionaryKey:@"CFBundleIconFile"];
if (iconFile) {
NSString *iconPath = [bundle pathForResource:iconFile ofType:@"icns"];
// load and display the icon
}
那么,如果不是通过驱动top
,您想要如何做到这一点呢?
好吧,你要求的其实不是一个明确的东西。OS有四个不同的任务/进程/程序/应用程序的概念,它们不对应于1-1,如果您想要编写两个使用不同概念的程序的混搭(例如,在BSD进程中使用top
处理,而活动监视器在OS应用程序中处理),这会使生活变得困难。
如果您真正想要的是top
使用的相同的列表,那么它是开源的,所以您可以使用读一读并做同样的事情。
但是获取BSD进程列表的最简单方法可能是libproc.h
中的接口,特别是proc_listallpids
和proc_pidinfo
。例如:
int dump_proc_names() {
int buf[16384];
int count = proc_listallpids(&buf, 16384*sizeof(int));
for (int i = 0; i != count; ++i) {
int pid = buf[i];
char path[MAXPATHLEN+1] = {0};
int ret = proc_pidinfo(pid, PROC_PIDPATHINFO, 0,
&path, sizeof(path));
if (ret < 0) {
printf("%d: error %s (%d)\n", pid, strerror(errno), errno);
} else {
printf("%d: %s\n", pid, path);
}
}
}
显然,在实际代码中,您需要动态分配缓冲区,返回值,而不是仅仅转储它们,获得的不仅仅是路径,等等。但这足以给您提供基本的想法。(当您要获取其他信息时,请注意,如果您要求任何结构,除非您有权查看该结构的每个成员,否则您将得到EPERM错误。所以,如果你只想要PROC_PIDTASKALLINFO
,就不要去问PROC_PIDT_SHORTBSDINFO
。
无论如何,由于这个API处理的是BSD进程(和Mach任务),而不是应用程序,所以它不会直接帮助您获得您想要提供活动监视器样式特性的NSBundle
。
没有办法做到这一点是完全正确的,但您可能可以逃脱这样的事情:
NSString *path = processPath;
while (path && ![path isEqualTo:@"/"]) {
NSBundle *bundle = [NSBundle bundleWithPath:path];
if (bundle) {
if ([bundle executablePath != processPath]) return nil;
return bundle;
}
path = [path stringByDeletingLastPathComponent];
}
要做到这一点,可能有其他的方法,每种方法都有不同的权衡。例如,使用-[NSWorkspace runningApplications]
将结果存储在字典中,将包可执行路径映射到包,并使用它查找每个进程,但它似乎只对当前用户(可能在当前会话中)拥有的应用程序有用。另一方面,枚举系统上的所有包,或者询问Spotlight或类似的程序,可能太慢了,但如果在第一次运行时缓存它们,就会过时。
替代libproc
的另一个选项是使用libtop
。
不幸的是,苹果并没有提供这种服务。他们确实有一个libtop
实现,用于他们的top
工具,但它实际上是嵌入到top
源代码中的,不能从外部获得。您可以找到源代码(在上面的链接中),并以top
本身的方式将其嵌入到程序中。
或者,GNU和BSD进程实用程序都有Mac端口(尽管知道在Homebrew/MacPorts/Google中使用哪个名称并不总是容易的…),这样你就可以建造其中之一并使用它。
但是,除非您试图编写跨平台软件(或者已经知道如何为linux或FreeBSD或其他什么编写此代码),否则我认为这只会增加额外的复杂性。
https://stackoverflow.com/questions/14368319
复制相似问题