Как определить версию ОС во время выполнения в OS X или iOS (без использования Gestalt)?
функция Gestalt (), расположенная в CarbonCore/OSUtils.h
был устаревшим с OS X 10.8 Mountain Lion.
Я часто использую эту функцию для тестирования версии операционной системы OS X во время выполнения (см. пример игрушки ниже).
какой другой API можно использовать для проверки версии операционной системы OS X во время выполнения в приложении Cocoa?
int main() {
SInt32 versMaj, versMin, versBugFix;
Gestalt(gestaltSystemVersionMajor, &versMaj);
Gestalt(gestaltSystemVersionMinor, &versMin);
Gestalt(gestaltSystemVersionBugFix, &versBugFix);
printf("OS X Version: %d.%d.%dn", versMaj, versMin, versBugFix);
}
12 ответов:
на OS X 10.10 (и iOS 8.0), вы можете использовать
[[NSProcessInfo processInfo] operatingSystemVersion]
который возвращает aNSOperatingSystemVersion
структура, определяемая какtypedef struct { NSInteger majorVersion; NSInteger minorVersion; NSInteger patchVersion; } NSOperatingSystemVersion;
существует также метод в NSProcessInfo, который будет делать сравнение для вас:
- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
будьте осторожны, хотя документально доступны в OS X 10.10 и более поздних версиях, оба
operatingSystemVersion
иisOperatingSystemAtLeastVersion:
существует на OS X 10.9 (наверное 10.9.2) и работает, как ожидалось. Это означает, что вы не должны проверить, еслиNSProcessInfo
реагирует на эти селекторы чтобы проверить, если вы работаете на OS X 10.9 или 10.10.на iOS эти методы эффективно доступны только с iOS 8.0.
в командной строке:
$ 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\n", kern.version[0], kern.version[1], kern.version[2]); printf("up: %d %d eq %d %d low %d %d\n", 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"); }
есть какао API. Вы можете получить строку версии os X из класса NSProcessInfo.
ниже приведен код для получения строки версии операционной системы..
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 greater.") }
или, проще говоря, вот код:
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; NSString *productVersion = [version objectForKey:@"ProductVersion"]; NSLog (@"productVersion =========== %@", productVersion);
Я надеюсь, что это кому-то поможет.
вы можете легко получить основную, второстепенную, патч-версию операционной системы с помощью
NSOperatingSystemVersion
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; NSString* major = [NSString stringWithFormat:@"%d", version.majorVersion]; NSString* minor = [NSString stringWithFormat:@"%d", version.minorVersion]; NSString* patch = [NSString stringWithFormat:@"%d", version.patchVersion];
вот что я использую:
NSInteger osxVersion; if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6) { //10.6.x or earlier systems osxVersion = 106; NSLog(@"Mac OSX Snow Leopard"); } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_7) { /* On a 10.7 - 10.7.x system */ osxVersion = 107; NSLog(@"Mac OSX Lion"); } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_8) { /* On a 10.8 - 10.8.x system */ osxVersion = 108; NSLog(@"Mac OSX Moutain Lion"); } else { /* 10.9 or later system */ osxVersion = 109; NSLog(@"Mac OSX: Mavericks or Later"); }
рекомендуется Примечания К Выпуску AppKit
Чтение / Система / Библиотека/CoreServices / SystemVersion.plist-это не возможно, если приложение является изолированное
Если у вас есть приложение, которое нужно запустить на 10.10, а также предыдущие версии, вот решение:
typedef struct { NSInteger majorVersion; NSInteger minorVersion; NSInteger patchVersion; } MyOperatingSystemVersion; if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { MyOperatingSystemVersion version = ((MyOperatingSystemVersion(*)(id, SEL))objc_msgSend_stret)([NSProcessInfo processInfo], @selector(operatingSystemVersion)); // do whatever you want with the version struct here } else { UInt32 systemVersion = 0; OSStatus err = Gestalt(gestaltSystemVersion, (SInt32 *) &systemVersion); // do whatever you want with the systemVersion as before }
обратите внимание, что даже 10.9, похоже, отвечает на селектор operatingSystemVersion, поэтому я думаю, что это просто частный API в 10.9 (но все еще работает).
это работает на всех версиях OS X и не полагается на синтаксический анализ строк или файловый ввод-вывод
здесь
uname(3)
:The
uname()
функция хранит нулевые строки информации, идентифицирующие текущую систему в структуре, на которую ссылаетсяname
.The
utsname
структура определяется в<sys/utsname.h>
заголовочный файл, и содержит следующие элементы:
sysname
- имя реализация операционной системы.nodename
- сетевое имя этой машины.release
- уровень выпуска операционной системы.version
- версия операционной системы.machine
- аппаратной платформы машины.
это на самом деле компиляция ответов выше, с некоторым дальнейшим руководством для нуждающегося разработчика.
OS-X предоставляет свою версию во время выполнения несколькими способами. Каждый способ лучше подходит для конкретного сценария развития. Я постараюсь обобщить их все и надеюсь, что другие завершат мой ответ, если я что-то забыл.
во-первых, полный список способов получения версии ОС.
- The инструмент и функция предоставляет версию ОС unix (darwin). Хотя это не маркетинговая версия ОС, она согласована с ней однозначно, поэтому вы можете вывести из нее маркетинговую версию OS-X.
sysctl kern.osrelease
командная строка (илиsysctlbyname("kern.osrelease", str, &size, NULL, 0)
функция) предоставит ту же информацию, что и uname, незначительно легче разобрать.Gestalt(gestaltSystemVersionMajor)
(С "Minor
" иBugFix
" варианты самые старые (пре-углерод!) API, чтобы получить версию маркетинговой ОС, по-прежнему поддерживается давно устаревшим. Доступно в C из фреймворка CoreServices, но не рекомендуется.NSAppKitVersionNumber
является плавающей константой фреймворка AppKit, которая обеспечит версию OS-X Appkit (выровненную с версией ОС), доступную для всех приложений, которые ссылаются на AppKit. Он также обеспечивает полное перечисление всех возможных версий (например,NSAppKitVersionNumber10_7_2
)kCFCoreFoundationVersionNumber
в рамках CoreFoundation флоат-постоянная, одинаковая для Appkit коллеги, доступен для всех приложений, связанных против CoreFoundation, как в C, Obj-C, так и в Swift. Он также обеспечивает полное перечисление всех выпущенных версий OS X (например,kCFCoreFoundationVersionNumber10_9
)[[NSProcessInfo processInfo] operatingSystemVersionString];
это API Cocoa, доступный в Obj-C для приложений OS-X и iOS.- есть ресурс .plist в
/System/Library/CoreServices/SystemVersion.plist
который среди прочего содержит версию ОС в ключе "ProductVersion". NSProcessInfo считывает информацию из этого файла, но вы можете сделать это непосредственно с помощью вашего plist-reading API выбор.для получения более подробной информации о каждом варианте - пожалуйста, обратитесь к ответам выше. Там полно информации!
поздно к игре, но я в конечном итоге здесь ищет ответ, а также. Для чего это стоит, может это для кого-то другого;
в прошлом я использовал подход командной строки:
sw_vers
что приводит к:
ProductName: Mac OS X ProductVersion: 10.13.6 BuildVersion: 17G65
каждая строка может быть запрошена индивидуально (помните нотацию camelback):
sw_vers -productVersion 10.13.6 sw_vers -productName Mac OS X sw_vers -buildVersion 17G65
сказав, что спасибо за все другие решения, перечисленные здесь ...