The Cocoa doesn’t seem to provide an easy way to check if a process you wanted to check is rurrning.
So, I wrote a simple Objective-C class for that purpose.
(If you have some great idea how to get absolute paths for running processes, please tell me. I’d like to add the feature to this class.)
Source 1 : JAProcessInfo.h
#import <Cocoa/Cocoa.h>
@interface JAProcessInfo : NSObject {
@private
int numberOfProcesses;
NSMutableArray *processList;
}
- (id) init;
- (int)numberOfProcesses;
- (void)obtainFreshProcessList;
- (BOOL)findProcessWithName:(NSString *)procNameToSearch;
@end
Source 2 : JAProcessInfo.m
#import "JAProcessInfo.h"
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/sysctl.h>
typedef struct kinfo_proc kinfo_proc;
@implementation JAProcessInfo
- (id) init
{
self = [super init];
if (self != nil)
{
numberOfProcesses = -1; // means "not initialized"
processList = NULL;
}
return self;
}
- (int)numberOfProcesses
{
return numberOfProcesses;
}
- (void)setNumberOfProcesses:(int)num
{
numberOfProcesses = num;
}
- (int)getBSDProcessList:(kinfo_proc **)procList
withNumberOfProcesses:(size_t *)procCount
{
int err;
kinfo_proc * result;
bool done;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
size_t length;
// a valid pointer procList holder should be passed
assert( procList != NULL );
// But it should not be pre-allocated
assert( *procList == NULL );
// a valid pointer to procCount should be passed
assert( procCount != NULL );
*procCount = 0;
result = NULL;
done = false;
do
{
assert( result == NULL );
// Call sysctl with a NULL buffer to get proper length
length = 0;
err = sysctl((int *)name,(sizeof(name)/sizeof(*name))-1,NULL,&length,NULL,0);
if( err == -1 )
err = errno;
// Now, proper length is optained
if( err == 0 )
{
result = malloc(length);
if( result == NULL )
err = ENOMEM; // not allocated
}
if( err == 0 )
{
err = sysctl( (int *)name, (sizeof(name)/sizeof(*name))-1, result, &length, NULL, 0);
if( err == -1 )
err = errno;
if( err == 0 )
done = true;
else if( err == ENOMEM )
{
assert( result != NULL );
free( result );
result = NULL;
err = 0;
}
}
}while ( err == 0 && !done );
// Clean up and establish post condition
if( err != 0 && result != NULL )
{
free(result);
result = NULL;
}
*procList = result; // will return the result as procList
if( err == 0 )
*procCount = length / sizeof( kinfo_proc );
assert( (err == 0) == (*procList != NULL ) );
return err;
}
- (void)obtainFreshProcessList
{
int i;
kinfo_proc *allProcs = 0;
size_t numProcs;
NSString *procName;
int err = [self getBSDProcessList:&allProcs withNumberOfProcesses:&numProcs];
if( err )
{
numberOfProcesses = -1;
processList = NULL;
return;
}
// Construct an array for ( process name )
processList = [NSMutableArray arrayWithCapacity:numProcs];
for( i = 0; i < numProcs; i++ )
{
procName = [NSString stringWithFormat:@"%s", allProcs[i].kp_proc.p_comm];
[processList addObject:procName];
}
[self setNumberOfProcesses:numProcs];
// NSLog(@"# of elements = %d total # of process = %d\n",
// [processArray count], numProcs );
free( allProcs );
}
- (BOOL)findProcessWithName:(NSString *)procNameToSearch
{
int index;
index = [processList indexOfObject:procNameToSearch];
if( index == NSNotFound )
return NO;
else
return YES;
}
@end
How to use it?
JAProcessInfo *procInfo = [[JAProcessInfo alloc] init]; [procInfo obtainFreshProcessList]; // Get a list of process BOOL isRunning = [procInfo findProcessWithName:@"mlnet"];
Entire (RSS)
Posted by Patrick on September 11, 2009 at 7:24 am
Thanks. Took me a bit to find this, but it’s exactly what I was looking for.
Posted by jongampark on September 12, 2009 at 9:48 pm
Hi, Patrick.
I found a better solution that the code above. In Cocoa, there was already a method for the purpose.
However, probably it was not available for earlier Mac OS X.
Posted by jonathan Mitchell on September 29, 2009 at 4:31 am
I think that this code still has validity. Other existing Cocoa methods are not so comprehensive in the process info that they return.
Note that line 144 can be improved upon
index = [processList indexOfObject:[procNameToSearch substringToIndex:MAXCOMLEN]];
Thanks for the code.
Posted by prathumca on December 18, 2009 at 11:21 am
Thanks Man,
You saved my day.