2016-07-29 24 views
2

Wie kann ich abrufen folgende Informationen programmatisch in C++:Wie OS X Board-Informationen abrufen programmatisch

Dies ist ein Terminal-Befehl in Mac OSX:

ioreg -c IOPlatformExpertDevice | awk '/board-id/ {print $4}' | awk -F '\"' '{print $2}' 

verwende ich IOKit Bibliothek Informationen abrufen wie IOPlatformSerialNumber- und PlatformUUID-Informationen. Aber ich konnte keinen passenden Schlüssel für "board-id" finden.

+0

Als am wenigsten Ort, könnten Sie 'Rohr()' und die Befehlszeile aus Ihrer Frage. –

+1

'popen()' sicher? –

+1

@MarkSetchl Es tut uns leid, vertippt. –

Antwort

1

Wenn Sie die io_service_t Handle zu IOPlatformExpertDevice in Ihrem C++ - Code haben, können Sie die IORegistryEntryCreateCFProperty() Funktion verwenden, um die "Board-ID" -Eigenschaft zu erhalten. Erwarten Sie, ein CFData Objekt zu erhalten, aber überprüfen Sie auf Null und die richtige Typen-ID, um sicher zu sein. Verwenden Sie dann die üblichen Methoden CFData, um die Daten in der gewünschten Form zu extrahieren.

Wenn Sie nicht der IOService noch handhaben erhalten haben, sollten Sie in der Lage sein, dort zu bekommen entweder IOServiceGetMatchingService() (ich hoffe, es ist sicher nur davon ausgehen, es wird eine IOPlatformExpertDevice Instanz sein.) Oder mit IORegistryGetRootEntry() die bekommen root, und das IORegistry-Diagramm mit dem Plattform-Expertengerät mit IORegistryEntryGetChildEntry() oder ähnlichem durchlaufen.

Da die board-id Eigenschaft keinen Namen symbolische Konstante haben, werden Sie es einfach hart codieren haben:

CFTypeRef board_id_property = IORegistryEntryCreateCFProperty(
    platform_expert_device, CFSTR("board-id"), kCFAllocatorDefault, 0); 

Beachten Sie, dass Eigenschaftswerte verschiedene Arten erfolgen, einschließlich CFNumber, CFBoolean, CFString, CFData , CFArray und CFDictionary, und Sie müssen darauf vorbereitet sein, den Fall zu behandeln, in dem der Typ nicht dem erwarteten entspricht oder wenn NULL zurückgegeben wird (wenn die Eigenschaft nicht existiert). Überprüfen Sie den Typ mit CFGetTypeID(), z.B .:

if (board_id_property != NULL && CFGetTypeID(board_id_property) == CFDataGetTypeID()) 
{ 
    CFDataRef board_id_data = (CFDataRef)board_id_property; 
    // safe to use CFData* functions now 
    ... 

    CFRelease(board_id_property); 
} 
else 
{ 
    // Unexpected, do error handling. 
    ... 

    if (board_id_property != NULL) 
     CFRelease(board_id_property); 
} 
+0

Ich habe io_service_t handle, aber es gibt keinen Schlüssel für "board-id", da es einen für kIOPlatformSerialNumberKey gibt. –

+0

Es ist nur eine Zeichenfolge, die in verschiedenen Bits des OS X-Quellcodes ohne eine symbolische Konstante fest codiert zu sein scheint. Sie müssen nur die rohe Zeichenfolge verwenden. – pmdj

+0

Also habe ich versucht, was Sie vorgeschlagen, d. H. Mit rohen Zeichenfolge. Nächste 2 Versuche scheiterten mit Fehler "- [__ NSCFData _fastCharacterContents]: unerkannter Selektor an Instanz gesendet ...": IORegistryEntryCreateCFProperty (platformExpert, CFSTR ("board-id"), kCFAllocatorDefault, 0) & IORegistryEntryCreateCFProperty (platformExpert, CFSTR ("Hersteller")), kCFALLocatorDefault, 0). IORegistryEntryCreateCFProperty (platformExpert, CFSTR ("IOPolledInterface"), kCFAllocatorDefault, 0) ist jedoch erfolgreich. Wenn Sie den Terminalbefehl "ioreg -rd1 -c IOPlatformExpertDevice" ausführen, gibt es Unterschiede bei der Benennung dieser Variablen. –