【问题标题】:How to retrieve OS X board-id information programmatically如何以编程方式检索 OS X board-id 信息
【发布时间】:2016-12-04 13:51:08
【问题描述】:

如何在 c++ 中以编程方式检索以下信息:

这是 Mac OSX 中的终端命令:

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

我使用 IOKit 库来检索 IOPlatformSerialNumber 和 PlatformUUID 信息等信息。但是我找不到“board-id”的任何对应键。

【问题讨论】:

  • 至少可以使用pipe() 和问题中的命令行。
  • @MarkSetchell 抱歉,打错了。
  • 我不想使用 popen() 从我的代码中执行任何命令行语句,因为它不那么可靠。假设如果我使用一些“awk”或“sed”实用程序以及命令行语句来解析出我需要的值,那么我会做出以下巨大的假设:1.其他用户在他们的机器上拥有这些实用程序 2.这些实用程序是有效的而不是一些与标准实用程序同名的恶意代码。为了防止在这些情况下出现错误,最好使用内置系统库并尽可能从产品代码中调用它们。感谢您的建议。

标签: c++ macos awk iokit sysinfo


【解决方案1】:

如果您的 C++ 代码中有 IOPlatformExpertDeviceio_service_t 句柄,则可以使用 IORegistryEntryCreateCFProperty() 函数获取“board-id”属性。期望收到CFData 对象,但请检查 null 和正确的类型 id 以确保。然后,使用通常的CFData 方法以您想要的形式提取数据。

如果您还没有 IOService 句柄,您应该可以使用IOServiceGetMatchingService()(我希望可以安全地假设只有一个IOPlatformExpertDevice 实例。)或使用@ 987654328@ 获取根,然后将 IORegistry 图传送到具有IORegistryEntryGetChildEntry() 或类似名称的平台专家设备。

由于board-id 属性没有命名符号常量,您只需对其进行硬编码:

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

请注意,属性值可以采用不同的类型,包括CFNumberCFBooleanCFStringCFDataCFArrayCFDictionary,您需要准备好处理以下情况类型与您期望的不匹配,或者返回 NULL 时(如果属性不存在)。使用CFGetTypeID()检查类型,例如:

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);
}

【讨论】:

  • 我有 io_service_t 句柄,但没有“board-id”的键,因为 kIOPlatformSerialNumberKey 有一个。
  • 它只是一个字符串,似乎在 OS X 源代码的各个位中硬编码,没有符号常量。你只需要使用原始字符串。
  • 所以我尝试了你的建议,即使用原始字符串。接下来的 2 次尝试失败,出现错误“-[__NSCFData _fastCharacterContents]:无法识别的选择器已发送到实例 ...”:IORegistryEntryCreateCFProperty(platformExpert, CFSTR("board-id"), kCFAllocatorDefault, 0) & IORegistryEntryCreateCFProperty(platformExpert, CFSTR("manufacturer" ), kCFAllocatorDefault, 0)。但是, IORegistryEntryCreateCFProperty(platformExpert, CFSTR("IOPolledInterface"), kCFAllocatorDefault, 0) 成功。当您运行“ioreg -rd1 -c IOPlatformExpertDevice”终端命令时,这些变量的命名会有所不同。
  • 我认为小写命名的属性可能在某些不同的注册表项下,而不是在io下。这只是一个猜测,但不确定。
  • 非常感谢,非常感谢您的帮助。我听从了你的建议,检索了 CFDataRef ,然后转换为 std::string 用于打印目的,我得到的值与终端命令完全相同。为什么苹果文档如此糟糕,与他们的系统编程有关!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
相关资源
最近更新 更多