Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jun 12, 2009, 03:19 AM   #1
Jose Jayan
macrumors newbie
 
Join Date: Jun 2009
Getting Hardware Details from Objective-C

Hi there

I want to write a cocoa app which will retrieve the following machine details.

CPU Model,CPU ID
Machine Name, Machine IP
Hard Disk Details
RAM Details
Operating System


Could you people please advice me on this(Instead of calling system_profiler from terminal)?
Jose Jayan is offline   0 Reply With Quote
Old Jun 12, 2009, 05:07 AM   #2
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
There is no Cocoa API for this. You have to call into Carbon (if you can find an API for it: I haven't looked) or do what you have already ruled out: call out to the system_profiler command line.
robbieduncan is offline   0 Reply With Quote
Old Jun 12, 2009, 05:12 AM   #3
gnasher729
macrumors G5
 
gnasher729's Avatar
 
Join Date: Nov 2005
Quote:
Originally Posted by Jose Jayan View Post
Hi there

I want to write a cocoa app which will retrieve the following machine details.

CPU Model,CPU ID
Machine Name, Machine IP
Hard Disk Details
RAM Details
Operating System


Could you people please advice me on this(Instead of calling system_profiler from terminal)?
Search for "Gestalt".
Or use the power of Posix to call system_profiler from your application and read its output.
gnasher729 is offline   0 Reply With Quote
Old Jun 12, 2009, 07:21 AM   #4
Jose Jayan
Thread Starter
macrumors newbie
 
Join Date: Jun 2009
Quote:
Originally Posted by gnasher729 View Post
Search for "Gestalt".
Or use the power of Posix to call system_profiler from your application and read its output.
But neither the Gestalt or system_profiler revealed the CPU Serial ID or MotherBoardID(Serial Number).
Also tried IOREG from terminal.
Jose Jayan is offline   0 Reply With Quote
Old Jun 12, 2009, 07:26 AM   #5
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Google gave me this in, like, 3 seconds: Google answer. Seriously: search.
robbieduncan is offline   0 Reply With Quote
Old Jun 12, 2009, 09:38 AM   #6
Guiyon
macrumors 6502a
 
Join Date: Mar 2008
Location: North Shore, MA
Depending on exactly what you need, you have several options other than relying on a dying API or brute-force searching through the output of an NSTask. For example, both the NSProcessInfo and the sysctl API can provide a significant amount of information about a system (and, in the case of sysctl, it's pretty portable). If you need even more detailed information there is also IOKit and, using that, you can grab everything down to each individual CPU's ID.

Just the file as "HWInfo.m" and compile it using:
Code:
gcc -framework "Foundation" -framework "IOKit" -o HWInfo HWInfo.m

Edit: Updated with code for grabbing CPUIDs and Serial Number using IOKit
Edit 2: Significantly condensed down the code for grabbing the serial number. It's just grabbing the root entry so setting up a matching dictionary, etc. is just overkill.
Edit 3: Last edit, I promise! Moved the sysctl stuff into its own function to make it a bit easier to parse. Replaced NSLog with objc_println.

Here is an example using NSProcessInfo, sysctl and the IOKit APIs:
Code:
#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>

#include <sys/sysctl.h>
#include <sys/resource.h>
#include <sys/vm.h>

static void objc_println( NSString* format, ... );
static void printSysctlInfo( void );
static NSDictionary* getCpuIds( void );
static NSString* getPlatformSerialNumber( void );

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  
  objc_println(@"Beginning system data collection...");
  
  NSProcessInfo* pinfo = [NSProcessInfo processInfo];
  
  objc_println( @"NSProcessInfo:" );
  objc_println( @"\tProcess Name: %@", [pinfo processName] );
  objc_println( @"\tPID: %d", [pinfo processIdentifier] );
  objc_println( @"\tProcess GUID: %@", [pinfo globallyUniqueString] );
  objc_println( @"\tOS Version: %@", [pinfo operatingSystemVersionString] );
  objc_println( @"\tTotal Processors: %d", [pinfo processorCount] );
  objc_println( @"\tActive Processors: %d", [pinfo activeProcessorCount] );
  objc_println( @"\tTotal RAM: %ull bytes", [pinfo physicalMemory] );
  
  printSysctlInfo();
  
  objc_println( @"IOKit:" );
  NSDictionary *cpuInfo = getCpuIds();
  NSArray* keys = [[cpuInfo allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  
  for( id key in keys ) {
    objc_println( @"\t%@ has ID: 0x%8.8x", key, [(NSNumber*)[cpuInfo objectForKey: key] unsignedIntValue] );
  }
  
  objc_println( @"\tSerial Number: %@", getPlatformSerialNumber() );
  
  [pool drain];
  
  return 0;
}

static void objc_println( NSString* format, ... ) {
  va_list args;

  if (![format hasSuffix: @"\n"]) {
    format = [format stringByAppendingString: @"\n"];
  }
	
  va_start (args, format);
  NSString *body =  [[NSString alloc] initWithFormat: format
                                           arguments: args];
  va_end (args);
	
  fprintf(stderr,"%s",[body UTF8String]);
  
  [body release];
}

static void printSysctlInfo( void ) {
  objc_println( @"sysctl:" );
  
  int mib[2];
  size_t len = 0;
  char *rstring = NULL;
  unsigned int rint = 0;
  
  /* Setup the MIB data */
  mib[0] = CTL_KERN;
  mib[1] = KERN_OSTYPE;
  
  /* Get the length of the string */
  sysctl( mib, 2, NULL, &len, NULL, 0 );
  
  /* Now allocate space for the string and grab it */
  rstring = malloc( len );
  sysctl( mib, 2, rstring, &len, NULL, 0 );
  objc_println( @"\tkern.ostype: %s", rstring );
  
  /* Make sure we clean up afterwards! */
  free( rstring );
  rstring = NULL;
  
  /* Get the kernel release number */
  mib[0] = CTL_KERN;
  mib[1] = KERN_OSRELEASE;
  sysctl( mib, 2, NULL, &len, NULL, 0 );
  rstring = malloc( len );
  sysctl( mib, 2, rstring, &len, NULL, 0 );
  objc_println( @"\tkern.osrelease: %s", rstring );
  free( rstring );
  rstring = NULL;
  
  /* Get the Mac OS X Build number */
  mib[0] = CTL_KERN;
  mib[1] = KERN_OSVERSION;
  sysctl( mib, 2, NULL, &len, NULL, 0 );
  rstring = malloc( len );
  sysctl( mib, 2, rstring, &len, NULL, 0 );
  objc_println( @"\tkern.osversion: %s", rstring );
  free( rstring );
  rstring = NULL;
  
  mib[0] = CTL_HW;
  mib[1] = HW_MODEL;
  sysctl( mib, 2, NULL, &len, NULL, 0 );
  rstring = malloc( len );
  sysctl( mib, 2, rstring, &len, NULL, 0 );
  objc_println( @"\thw.model: %s", rstring );
  free( rstring );
  rstring = NULL;
  
  sysctlbyname( "machdep.cpu.brand_string", NULL, &len, NULL, 0 );
  rstring = malloc( len );
  sysctlbyname( "machdep.cpu.brand_string", rstring, &len, NULL, 0 );
  objc_println( @"\tmachdep.cpu.brand_string: %s", rstring );
  free( rstring );
  rstring = NULL;
  
  mib[0] = CTL_HW;
  mib[1] = HW_CPU_FREQ;
  len = sizeof( rint );
  sysctl( mib, 2, &rint, &len, NULL, 0 );
  objc_println( @"\thw.cpufrequency: %u", rint );
}

static NSString* getPlatformSerialNumber( void ) {
  io_registry_entry_t     rootEntry = IORegistryEntryFromPath( kIOMasterPortDefault, "IOService:/" );
  CFTypeRef serialAsCFString = NULL;
  
  serialAsCFString = IORegistryEntryCreateCFProperty( rootEntry,
                                                     CFSTR(kIOPlatformSerialNumberKey),
                                                     kCFAllocatorDefault,
                                                     0);

  IOObjectRelease( rootEntry );
  return (NULL != serialAsCFString) ? [(NSString*)serialAsCFString autorelease] : nil;
}

static NSDictionary* getCpuIds( void ) {
  NSMutableDictionary*    cpuInfo = [[NSMutableDictionary alloc] init];
  CFMutableDictionaryRef  matchClasses = NULL;
  kern_return_t           kernResult = KERN_FAILURE;
  mach_port_t             machPort;
  io_iterator_t           serviceIterator;
  
  io_object_t             cpuService;
  
  kernResult = IOMasterPort( MACH_PORT_NULL, &machPort );
  if( KERN_SUCCESS != kernResult ) {
    printf( "IOMasterPort failed: %d\n", kernResult );
  }
  
  matchClasses = IOServiceNameMatching( "processor" );
  if( NULL == matchClasses ) {
    printf( "IOServiceMatching returned a NULL dictionary" );
  }
  
  kernResult = IOServiceGetMatchingServices( machPort, matchClasses, &serviceIterator );
  if( KERN_SUCCESS != kernResult ) {
    printf( "IOServiceGetMatchingServices failed: %d\n", kernResult );
  }
  
  while( (cpuService = IOIteratorNext( serviceIterator )) ) {
    CFTypeRef CPUIDAsCFNumber = NULL;
    io_name_t nameString;      
    IORegistryEntryGetNameInPlane( cpuService, kIOServicePlane, nameString );
    
    CPUIDAsCFNumber = IORegistryEntrySearchCFProperty( cpuService, 
                                                      kIOServicePlane,
                                                      CFSTR( "IOCPUID" ), 
                                                      kCFAllocatorDefault,
                                                      kIORegistryIterateRecursively);
    
    if( NULL != CPUIDAsCFNumber ) {
      NSString* cpuName = [NSString stringWithCString:nameString];
      [cpuInfo setObject:(NSNumber*)CPUIDAsCFNumber forKey:cpuName];
    }
    
    if( NULL != CPUIDAsCFNumber ) {
      CFRelease( CPUIDAsCFNumber );
    }
  }
  
  IOObjectRelease( serviceIterator );
  
  return [cpuInfo autorelease];
}
__________________
Make life easier if you have a programming question!
http://www.sscce.org/

Last edited by Guiyon; Jun 12, 2009 at 12:40 PM. Reason: Significantly condensed the getPlatformSerialNumber code (Thanks for the idea, larkost!)
Guiyon is offline   0 Reply With Quote
Old Jun 12, 2009, 11:00 AM   #7
larkost
macrumors 6502a
 
Join Date: Oct 2007
Ugg... do not go out to a NSTask for this. There is a perfectly serviceable API for this in the IOKit code. I wrote an article about this a while ago:

http://wranglingmacs.blogspot.com/20...st-string.html
larkost is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Objects in Objective C luke71933 Mac Programming 6 Apr 8, 2014 08:20 AM
Objective-C: What is subclassing? moonman239 Mac Programming 3 Feb 26, 2013 08:08 PM
C and Objective-C relationships nashyo iPhone/iPad Programming 16 Jan 21, 2013 05:48 AM
It's not about hardware. It's about software that runs hardware. stu00a iPad 7 Oct 24, 2012 04:03 PM
What type of hardware do I need for editing specific type of video? (Details inside) Reminisce32 Buying Tips and Advice 4 Oct 23, 2012 02:13 AM

Forum Jump

All times are GMT -5. The time now is 05:52 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC