最近在写一个小程序,需要查找当前运行的进程。于是翻sdk,查google,今天终于有点眉目了。
记录一下。
- (IBAction) signal:(id)sender
{
ProcessSerialNumber psn = { 0, kNoProcess };
OSErr result;
NSDictionary * dict;
if ((result=GetNextProcess(&psn))!=noErr)
NSLog(@"you've got trouble to get the first process serial number");
else
{
do {
dict=(NSDictionary *)ProcessInformationCopyDictionary(&psn,kProcessDictionaryIncludeAllInformationMask);
NSLog(@"i am alive %s",[[dict objectForKey:@"CFBundleName"] UTF8String]);
//NSLog(@"another way to get %s",[[dict description] UTF8String]);
result=GetNextProcess(&psn);
} while (result==noErr);
switch (result)
{
case procNotFound:
NSLog(@"at the end of process chain");
break;
default:
NSLog(@"other error %d occurred",result);
break;
}
}
}
|
在mac os x下开发有两类库,一类是carbon,一类是cocoa。前者用c写的,后者用objective c 写的。由于objective c兼容c,所以两者可以混用。
取系统进程,是carbon库所支持的功能。所以,这里的写法,基本上就是c的写法,看不出有cocoa的痕迹。
取系统进程用到的函数是GetNextProcess。通过不断调用这个函数,我们可以遍历整个进程链。(因为系统的所有进程就是串在一棵进程树上的)。
调用GetNextProcess,仅仅是返回一个进程编号(不等于unix下的pid),要获取进程的详细信息,需要这个函数 -- ProcessInformationCopyDictionary 。它把和这个进程编号对应的进程信息全部填入到一个dictionary的机构中。苹果太喜欢用dictionary了,一开始真不习惯。
这个dictionary里面有很多内容,具体可以查文档,我这里用到了一个字段,kCFBundleNameKey,就是进程的bundle名。
但是取key对应的值也不是那么简单的,还要通过CFDictionaryGetValue来取。而且取出来的值,需要事先搞清楚其数据类型。如果是字符型,还需要搞清楚字符的编码。
对于字符型的值,如果需要访问,可以通过CFStringGetCString,获得char *的数据。然后就可以在其他代码里访问了。
但是这个流程实在太麻烦了,所以还是想想更简单的办法。那就是看看CFDictionary和NSDictionary是什么关系。在网上查了一下,其实两者是等价的。但是后者可简单多了。
所以把程序改写了一下,用NSDictionary来处理结果,本来很复杂的程序,一下就简单多了。看来cocoa还是很好的东西。
整个过程在搞清楚之后,还是比较简单的。但是在研究阶段,还是一头雾水。主要是对苹果开发的习惯不是很熟悉。
阅读(3815) | 评论(1) | 转发(0) |