如何在 C/C++ 中为 macOS 获取产品名称/版本(即获取“Mac OS”和“10.12.5”)

Posted

技术标签:

【中文标题】如何在 C/C++ 中为 macOS 获取产品名称/版本(即获取“Mac OS”和“10.12.5”)【英文标题】:How to get product name/version in C/C++ for macOS (ie get "Mac OS" and "10.12.5") 【发布时间】:2017-11-24 18:46:01 【问题描述】:

我需要获取标题中的信息。我对以下变量进行了 sysctl 调用,它给了我其他(无用)信息(通常与内核而非操作系统有关):KERN_VERSION、KERN_OSVERSION、KERN_TYPE、KERN_RELEASE。

我在这里查看了命令sw_vers 的源代码:https://opensource.apple.com/source/DarwinTools/DarwinTools-1/sw_vers.c 并尝试实现他们所做的,但是当我能够包含我的计算机时无法找到,因此我无法实现。当我查看我的 /include/ 目录时,我根本找不到 /CoreFoundation/ 所以我不知道我从哪里拉它。

关于如何使用 C/C++ 实现这一点的任何想法?

谢谢

【问题讨论】:

你没有做太多的研究,是吗?我在 30 秒内用 1 次谷歌搜索发现 KERN_VERSION 是在 sys/sysctl.h 中定义的。也许使用在同一个标​​题中定义的sysctl_rdstring 会让你到达某个地方。 请注意,10.12.5 是 macOS Sierra 的一个版本——macOS 部分的大小写不同。 @MichaëlRoy:我认为你错过了重点——OP 知道这些,但他们没有提供想要的答案。 你引用的开源存储库有这个目录:opensource.apple.com/source/CF,它似乎包含 CoreFoundation 源代码。执行sw_vers 并解析其输出不是一个选项吗? 可以做到——sw_vers 程序证明了它可以做到。不太清楚的是sw_vers 程序在做什么。它在询问什么信息来查找信息。如果你发现它涉及到使用一些 Objective-C 代码,那可以接受吗?我注意到man sw_vers 表明您可以使用一个选项调用它,以获取任何没有标签前缀的字段(sw_vers -productName — 单破折号)。它还提到了文件/System/Library/CoreServices/SystemVersion.plist/System/Library/CoreServices/ServerVersion.plist——这有帮助吗? 【参考方案1】:

如果这是我的项目,我会简单地调用sw_vers 实用程序并解析其输出。您可以使用popen 来完成此操作,如下图所示:

char buf[1024];
unsigned buflen = 0;
char line[256];
FILE *sw_vers = popen("sw_vers", "r");
while (fgets(line, sizeof(line), sw_vers) != NULL) 
    int l = snprintf(buf + buflen, sizeof(buf) - buflen, "%s", line);
    buflen += l;
    assert(buflen < sizeof(buf));

pclose(sw_vers);

解析输出以获取相关信息。在我的系统上,输出是:

ProductName:    Mac OS X
ProductVersion: 10.12.5
BuildVersion:   16F73

因此,您可以解析每一行,而不是如图所示将其全部存储到缓冲区中。

一旦信息存储在您的程序中,结果就可以被缓存。您的同一程序将来的任何查询都可以使用缓存的结果,而不是再次调用sw_vers

【讨论】:

您还可以添加参数以使结果具体化。例如: sw_vers -productVersion(为您提供操作系统版本号,如 10.11.1) sw_vers -buildVersion(为您提供类似 15E01 的内容) sw_vers -productName(为您提供类似“Mac OS X”的内容) 如果系统区域设置不是英语怎么办?解析会失败吗? @VikasPushkar:您可以使用命令行来指定感兴趣的信息,正如Neilvert 所建议的那样,或者您可以改为逐行解析(因为每行代表特定顺序的信息)。

以上是关于如何在 C/C++ 中为 macOS 获取产品名称/版本(即获取“Mac OS”和“10.12.5”)的主要内容,如果未能解决你的问题,请参考以下文章

如何在where子句中为每个名称最多获取两个条目[重复]

试图获取非对象的属性“名称”(视图:(...)资源/视图/产品/index.blade.php)

如何在 iOS/macOS 云共享相册中为照片附加短数据?

在 Cocoa macOS 应用程序中,如何获取 MKMapView 左下角的度数坐标?

如何在沙盒 macOS 应用程序中为 ImageEvent 类运行 AppleScript?

如何在透视中为列提供自定义名称