如何在OS X或iOS中运行OS版本(不使用Gestalt)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在OS X或iOS中运行OS版本(不使用Gestalt)?相关的知识,希望对你有一定的参考价值。

位于CarbonCore/OSUtils.h的Gestalt()函数自OS X 10.8 Mountain Lion起已被弃用。

我经常使用此函数在运行时测试OS X操作系统的版本(参见下面的玩具示例)。

在Cocoa应用程序中,可以使用哪些其他API在运行时检查OS X操作系统版本?

int main() {
    SInt32 versMaj, versMin, versBugFix;
    Gestalt(gestaltSystemVersionMajor, &versMaj);
    Gestalt(gestaltSystemVersionMinor, &versMin);
    Gestalt(gestaltSystemVersionBugFix, &versBugFix);

    printf("OS X Version: %d.%d.%d
", versMaj, versMin, versBugFix);
}
答案

在OS X 10.10(和ios 8.0)上,您可以使用[[NSProcessInfo processInfo] operatingSystemVersion]返回NSOperatingSystemVersion结构,定义为

typedef struct {
    NSInteger majorVersion;
    NSInteger minorVersion;
    NSInteger patchVersion;
} NSOperatingSystemVersion;

NSProcessInfo中还有一个方法可以为您进行比较:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

请注意,虽然记录在OS X 10.10及更高版本中可用,但是OS X 10.9(operatingSystemVersion)上存在isOperatingSystemAtLeastVersion:probably 10.9.2,并且按预期工作。这意味着您不能测试NSProcessInfo是否响应这些选择器以检查您是否在OS X 10.9或10.10上运行。

在iOS上,这些方法实际上仅在iOS 8.0之后可用。

另一答案

uname(3)

qazxsw poi函数存储以null结尾的信息字符串,用于将当前系统标识为uname()引用的结构。

name结构在utsname头文件中定义,包含以下成员:

  • <sys/utsname.h> - 操作系统实现的名称。
  • sysname - 本机的网络名称。
  • nodename - 操作系统的发布级别。
  • release - 操作系统的版本级别。
  • version - 机器硬件平台。
另一答案

这实际上是上面答案的汇编,有一些进一步指导有需要的开发人员。

OS-X以多种方式在运行时提供其版本。每种方式都更适合特定的开发方案。我会试着总结一下,如果我忘记了什么,希望别人能完成我的答案。

首先,获取操作系统版本的综合方法列表。

  1. machine命令行工具和函数提供了操作系统的unix(darwin)版本。虽然这不是操作系统的营销版本,但它与其唯一对齐,因此您可以从中推断出OS-X营销版本。
  2. uname命令行(或sysctl kern.osrelease函数)将提供与uname相同的信息,稍微容易解析。
  3. sysctlbyname("kern.osrelease", str, &size, NULL, 0)(其“Gestalt(gestaltSystemVersionMajor)”和Minor“变体是获得营销操作系统版本的最古老的(前碳!)API,仍然受到长期弃用的支持。可从CoreServices框架获得C,但不推荐。
  4. BugFix是AppKit框架的浮点常量,它将提供OS-X Appkit版本(与操作系统版本一致),可用于链接AppKit的所有应用程序。它还提供了所有可能版本的全面列举(例如NSAppKitVersionNumber
  5. NSAppKitVersionNumber10_7_2是一个CoreFoundation框架浮点常量,与Appkit对应相同,可用于所有与CoreFoundation链接的应用程序,包括C,Obj-C和Swift。它也提供了所有OS X发布版本的全面枚举(例如kCFCoreFoundationVersionNumber
  6. kCFCoreFoundationVersionNumber10_9是Obj-C中可用于OS-X和iOS应用程序的Cocoa API。
  7. [[NSProcessInfo processInfo] operatingSystemVersionString];中有一个资源.plist,其中包含“ProductVersion”键中的操作系统版本。 NSProcessInfo从此文件中读取其信息,但您可以使用您选择的PList-reading API直接执行此操作。

有关每个选项的更多详细信息 - 请参阅上面的答案。那里有很多信息!

另一答案

今天在MacOS上玩/System/Library/CoreServices/SystemVersion.plist的时候我偶然发现了sysctl,它确实包含了当前的操作系统版本。在运行Mojave的Mac上,我得到:

kern.osproductversion

当然,也可以通过编程方式检索该值:

$ sysctl kern.osproductversion
kern.osproductversion: 10.14.3

char str[256]; size_t size = sizeof(str); int ret = sysctlbyname("kern.osproductversion", str, &size, NULL, 0); 到xnu内核代码库表明This commit是2018年中期出现的最新成员。我在10.14.3和10.13.6上成功测试了它。

总而言之,我认为最好的程序化,非Cocoa方法是检查osproductversion是否产生有效结果并回退到kern.osproductversionkern.osrelease中描述的手动映射。

另一答案

比赛结束,但我最终在这里寻找答案。对于它的价值,也许它可以用于其他人;

在过去,我使用命令行方法:

this answer

结果如下:

sw_vers

可以单独询问每一行(请注意驼峰符号):

ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G65

话虽如此,感谢此处列出的所有其他解决方案......

另一答案

在命令行上:

$ sysctl kern.osrelease
kern.osrelease: 12.0.0
$ sysctl kern.osversion
kern.osversion: 12A269

编程方式:

#include <errno.h>
#include <sys/sysctl.h>

char str[256];
size_t size = sizeof(str);
int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);

Darwin版本到OS X版本:

17.x.x. macOS 10.13.x High Sierra
16.x.x  macOS 10.12.x Sierra
15.x.x  OS X  10.11.x El Capitan
14.x.x  OS X  10.10.x Yosemite
13.x.x  OS X  10.9.x  Mavericks
12.x.x  OS X  10.8.x  Mountain Lion
11.x.x  OS X  10.7.x  Lion
10.x.x  OS X  10.6.x  Snow Leopard
 9.x.x  OS X  10.5.x  Leopard
 8.x.x  OS X  10.4.x  Tiger
 7.x.x  OS X  10.3.x  Panther
 6.x.x  OS X  10.2.x  Jaguar
 5.x    OS X  10.1.x  Puma

获取和测试版本的示例:

#include <string.h>
#include <stdio.h>
#include <sys/sysctl.h>

/* kernel version as major minor component*/
struct kern {
    short int version[3];
};

/* return the kernel version */
void GetKernelVersion(struct kern *k) {
   static short int version_[3] = {0};
   if (!version_[0]) {
      // just in case it fails someday
      version_[0] = version_[1] = version_[2] = -1;
      char str[256] = {0};
      size_t size = sizeof(str);
      int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
      if (ret == 0) sscanf(str, "%hd.%hd.%hd", &version_[0], &version_[1], &version_[2]);
    }
    memcpy(k->version, version_, sizeof(version_));
}

/* compare os version with a specific one
0 is equal
negative value if the installed version is less
positive value if the installed version is more
*/
int CompareKernelVersion(short int major, short int minor, short int component) {
    struct kern k;
    GetKernelVersion(&k);
    if ( k.version[0] !=  major) return major - k.version[0];
    if ( k.version[1] !=  minor) return minor - k.version[1];
    if ( k.version[2] !=  component) return component - k.version[2];
    return 0;
}

int main() {
   struct kern kern;
   GetKernelVersion(&kern);
   printf("%hd %hd %hd
", kern.version[0], kern.version[1], kern.version[2]);

   printf("up: %d %d eq %d %d low %d %d
",
        CompareKernelVersion(17, 0, 0), CompareKernelVersion(16, 3, 0),
        CompareKernelVersion(17, 3, 0), CompareKernelVersion(17,3,0),
        CompareKernelVersion(17,5,0), CompareKernelVersion(18,3,0));


}

结果我的机器macOs High Sierra 10.13.2

17 3 0
up: -3 -1 eq 0 0 low 2 1
另一答案

有NSAppKitVersionNumber值可用于检查各种版本的AppKit,尽管它们与操作系统版本不完全对应

if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_7_2) {
    NSLog (@"We are not running on Mountain Lion");
}
另一答案

有一个cocoa API。您可以从NSProcessInfo类获取os X版本字符串。

获取操作系统版本字符串的代码如下:

NSString * operatingSystemVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString];

NSLog(@"operatingSystemVersionString => %@" , operatingSystemVersionString);

// === >>版本10.8.2(Build 12C2034)结果值

它不会被弃用。

另一答案

如果您只需要检查支持的最低版本,还可以使用kCFCoreFoundationVersionNumber。这样做的好处是它可以回到10.1,可以用C,C ++和Objective-C完成。

例如,要检查10.10或更高:

#include <CoreFoundation/CoreFoundation.h>
if (floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9) {
    printf("On 10.10 or greater.");
}

您需要链接CoreFoundation(或Foundation)框架。

它也可以在Swift中以完全相同的方式工作。这是另一个例子:

import Foundation
if floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_8 {
    println("On 10.9 or greater.")
} else if floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9 {
    println("On 10.10 or 

以上是关于如何在OS X或iOS中运行OS版本(不使用Gestalt)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OS X 中升级 gcc 的 Clang 版本?

在 OS X 10.10 (Yosemite Beta) 中,如何使用 iOS 6.1 模拟器进行测试?

如何在Mac OS X上安装 Ruby运行环境

如何将 iPhone 用作 OS X、iOS 或 tvOS 的游戏控制器 [关闭]

如何让 kivy 在 OS X 上使用特定版本的 python?

如何在 shell 脚本中确定 Mac OS X 版本?