32

Mac OS X 开发对我来说是一个相当新的事物,我正在移植一些软件。对于软件许可和注册,我需要能够生成某种硬件 ID。它不必太花哨。以太网 MAC 地址、硬盘驱动器序列号、CPU 序列号等。

我已经在 Windows 上覆盖了它,但在 Mac 上我一无所知。任何关于我需要做什么的想法,或者我可以去哪里获取这方面的信息都会很棒!

编辑:

对于其他对此感兴趣的人,这是我最终与 Qt 的 QProcess 类一起使用的代码:

QProcess proc;

QStringList args;
args << "-c" << "ioreg -rd1 -c IOPlatformExpertDevice |  awk '/IOPlatformUUID/ { print $3; }'";
proc.start( "/bin/bash", args );
proc.waitForFinished();

QString uID = proc.readAll();

注意:我使用的是 C++。

4

8 回答 8

42

对于 C/C++:

void get_platform_uuid(char * buf, int bufSize) {
    io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
    CFStringRef uuidCf = (CFStringRef) IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
    IOObjectRelease(ioRegistryRoot);
    CFStringGetCString(uuidCf, buf, bufSize, kCFStringEncodingMacRoman);
    CFRelease(uuidCf);    
}
于 2010-05-02T18:56:51.973 回答
19

试试这个终端命令:

ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s\n", line[4]); }'

这里

这是包裹在 Cocoa 中的命令(可能会更简洁一些):

NSArray * args = [NSArray arrayWithObjects:@"-rd1", @"-c", @"IOPlatformExpertDevice", @"|", @"grep", @"model", nil];
NSTask * task = [NSTask new];
[task setLaunchPath:@"/usr/sbin/ioreg"];
[task setArguments:args];

NSPipe * pipe = [NSPipe new];
[task setStandardOutput:pipe];
[task launch];

NSArray * args2 = [NSArray arrayWithObjects:@"/IOPlatformUUID/ { split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }", nil];
NSTask * task2 = [NSTask new];
[task2 setLaunchPath:@"/usr/bin/awk"];
[task2 setArguments:args2];

NSPipe * pipe2 = [NSPipe new];
[task2 setStandardInput:pipe];
[task2 setStandardOutput:pipe2];
NSFileHandle * fileHandle2 = [pipe2 fileHandleForReading];
[task2 launch];

NSData * data = [fileHandle2 readDataToEndOfFile];
NSString * uuid = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
于 2009-06-03T10:44:50.810 回答
12

为什么不试试gethostuuid()?这是 Mac OS X 系统调用手册中的文档:

姓名:

 gethostuuid -- return a unique identifier for the current machine

概要:

 #include <unistd.h>

 int gethostuuid(uuid_t id, const struct timespec *wait);

描述:

gethostuuid() 函数返回一个由 id 指定的 16 字节 uuid_t,它唯一标识当前机器。请注意,gethostuuid() 用于生成 UUID 的硬件标识符本身可以被修改。

wait 参数是一个指向 struct timespec 的指针,它指定等待结果的最长时间。将 tv_sec 和 tv_nsec 字段设置为零意味着无限期地等待直到它完成。

返回值:

gethostuuid() 函数在成功时返回零,在错误时返回 -1。

错误

gethostuuid() 函数在以下情况下失败:

 [EFAULT]           wait points to memory that is not a valid part of the
                    process address space.

 [EWOULDBLOCK]      The wait timeout expired before the UUID could be
                    obtained.
于 2014-04-02T02:47:57.187 回答
9

如果您告诉我们您使用的语言,这将更容易回答。无需任何 shell 命令即可通过 SystemConfiguration 框架获取这些信息,如果您想亲自动手,也可以通过 IOKit 获取这些信息。

- (NSString*) getMACAddress: (BOOL)stripColons {
    NSMutableString         *macAddress         = nil;
    NSArray                 *allInterfaces      = (NSArray*)SCNetworkInterfaceCopyAll();
    NSEnumerator            *interfaceWalker    = [allInterfaces objectEnumerator];
    SCNetworkInterfaceRef   curInterface        = nil;

    while ( curInterface = (SCNetworkInterfaceRef)[interfaceWalker nextObject] ) {
        if ( [(NSString*)SCNetworkInterfaceGetBSDName(curInterface) isEqualToString:@"en0"] ) {
            macAddress = [[(NSString*)SCNetworkInterfaceGetHardwareAddressString(curInterface) mutableCopy] autorelease];

            if ( stripColons == YES ) {
                [macAddress replaceOccurrencesOfString: @":" withString: @"" options: NSLiteralSearch range: NSMakeRange(0, [macAddress length])];
            }

            break;
        }
    }

    return [[macAddress copy] autorelease];
}
于 2009-10-17T17:54:58.353 回答
6
/*
g++ mac_uuid.cpp -framework CoreFoundation -lIOKit
*/


#include <iostream>
#include <IOKit/IOKitLib.h>

using namespace std;

void get_platform_uuid(char * buf, int bufSize)
{
   io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
   CFStringRef uuidCf = (CFStringRef) IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
   IOObjectRelease(ioRegistryRoot);
   CFStringGetCString(uuidCf, buf, bufSize, kCFStringEncodingMacRoman);
   CFRelease(uuidCf);
}

int main()
{
   char buf[512] = "";
   get_platform_uuid(buf, sizeof(buf));
   cout << buf << endl;
}
于 2013-12-20T14:52:06.810 回答
1

跑步:

system_profiler | grep 'Serial Number (system)'

在终端中返回它可能是唯一的 id。这适用于我的 10.5 机器,我不确定在其他版本的 OS X 中正确的字符串是什么。

于 2009-06-01T03:43:55.363 回答
1

正如上面的一些人所暗示的那样,您可以使用终端命令来获取硬件 ID。

我假设您想在代码中执行此操作,因此我将查看 Cocoa 中的 NSTask 类。它基本上允许您在应用程序中运行终端命令。

此代码是如何在 Cocoa 中使用 NSTask 的示例。它设置环境以执行“killall”命令。它通过了争论“Finder”。

这相当于在命令行上运行“killall Finder”,这显然会杀死 Finder。

NSTask *aTask = [[NSTask alloc] init];
NSMutableArray *args = [NSMutableArray array];

[aTask setLaunchPath: @"/usr/bin/killall"];
[args addObject:[@"/Applications/Finder" lastPathComponent]];
[aTask setArguments:args];
[aTask launch];

[aTask release];
于 2009-06-03T10:50:22.170 回答
0

System Profiler(在应用程序 - 实用程序中)包含大部分此类信息。它有您的序列号和您的 mac 地址(与 Mac 无关。所有计算机都有一个 mac 地址,这对于每个网卡来说几乎都是唯一的)。

于 2009-06-03T10:30:52.040 回答