在OS X上获取模型标识符字符串

时间:2013-11-19 11:29:02

标签: macos cocoa core-foundation

每台Mac都有一个型号标识符,例如“Macmini5,1”。 (这些显示在“系统信息”应用程序中。)

enter image description here

我如何以编程方式获取此模型标识符字符串?

6 个答案:

答案 0 :(得分:3)

您可以使用sysctl

#import <Foundation/Foundation.h>
#import <sys/sysctl.h>

NSString *ModelIdentifier()
{
    NSString *result=@"Unknown Mac";
    size_t len=0;
    sysctlbyname("hw.model", NULL, &len, NULL, 0);
    if (len) {
        NSMutableData *data=[NSMutableData dataWithLength:len];
        sysctlbyname("hw.model", [data mutableBytes], &len, NULL, 0);
        result=[NSString stringWithUTF8String:[data bytes]];
    }
    return result;
}

答案 1 :(得分:3)

您也可以使用IOKit.framework。我认为这是最好的选择。

这个简单的代码示例演示了如何从I / O Kit注册表中将模型标识符读取到NSString

- (NSString *)modelIdentifier {
    io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, 
                                                       IOServiceMatching("IOPlatformExpertDevice"));

    CFStringRef model = IORegistryEntryCreateCFProperty(service, 
                                                        CFSTR("model"), 
                                                        kCFAllocatorDefault, 
                                                        0);

    NSString *modelIdentifier = [[NSString alloc] initWithData:(__bridge NSData *)model 
                                                      encoding:NSUTF8StringEncoding];

    CFRelease(model);
    IOObjectRelease(service);

    return modelIdentifier;
}

上面代码中的字符串“IOPlatformExpertDevice”“model”用于从I / O Kit注册表中读取模型标识符。当您想要从I / O Kit注册表中查找信息时,ioreg命令行工具是您的朋友。此图像显示ioreg输出中的那些字符串:

我希望这有助于使用IOKit.framework

答案 2 :(得分:3)

使用IOKit的Swift 4

public func getMacModel() -> String? {
    let service = IOServiceGetMatchingService(kIOMasterPortDefault,
                                              IOServiceMatching("IOPlatformExpertDevice"))
    var modelIdentifier: String?
    if let modelData = IORegistryEntryCreateCFProperty(service, "model" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data {
        modelIdentifier = String(data: modelData, encoding: .utf8)
    }

    IOObjectRelease(service)
    return modelIdentifier
}

答案 3 :(得分:2)

您可以从system_profiler命令获得相同的输出。它有一个-xml选项,您可以使用它。 NSTask可以为您运行命令,您可以解析结果。


示例代码:

#import <Foundation/Foundation.h>

NSString *ModelIdentifier() {
    NSPipe *pipe=[NSPipe pipe]; 
    NSTask *task=[[NSTask alloc] init];
    [task setLaunchPath:@"/usr/sbin/system_profiler"];
    [task setArguments:@[@"-xml", @"SPHardwareDataType"]];
    [task setStandardOutput:pipe];
    [task launch];

    NSData *outData=[[pipe fileHandleForReading] readDataToEndOfFile];
    NSString *outString=[[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
    return [outString propertyList][0][@"_items"][0][@"machine_model"];
}

答案 4 :(得分:1)

CFStringRef model = IORegistryEntryCreateCFProperty(service, 
                                                        CFSTR("model"), 
                                                        kCFAllocatorDefault, 
                                                        0);  ? type is ok ?

我认为代码可能是这样的:

CFSDataRef model = IORegistryEntryCreateCFProperty(service, 
                                                        CFSTR("model"), 
                                                        kCFAllocatorDefault, 
                                                        0);  

答案 5 :(得分:0)

Answer from Ryan H是正确的,除了从null-terminated stringSwift String的不正确转换之外,最终结果中带有\0符号的结果(您可能不会想到)会执行完全匹配。这是更正的版本:

static private func modelIdentifier() -> String? {
    let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
    defer { IOObjectRelease(service) }

    if let modelData = IORegistryEntryCreateCFProperty(service, "model" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data {
        return modelData.withUnsafeBytes { (cString: UnsafePointer<UInt8>) -> String in
            return String(cString: cString)
        }
    }

    return nil
}