Уникальный идентификатор оборудования в Mac OS X - PullRequest
27 голосов
/ 01 июня 2009

Разработка для Mac OS X - это довольно новое для меня животное, и я нахожусь в процессе портирования на какое-то программное обеспечение. Для лицензирования и регистрации программного обеспечения мне нужно иметь возможность генерировать какой-то идентификатор оборудования. Это не должно быть ничего фантастического; Ethernet MAC-адрес, последовательный жесткий диск, последовательный процессор, что-то в этом роде.

Я рассказал об этом в Windows, но не имею понятия о Mac. Любая идея о том, что мне нужно сделать, или куда я могу обратиться за информацией об этом, была бы отличной!

Edit:

Для всех, кто заинтересован в этом, это код, который я в конечном итоге использовал с классом Qtcess Qt:

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 ++.

Ответы [ 8 ]

35 голосов
/ 02 мая 2010

Для 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);    
}
15 голосов
/ 03 июня 2009

Попробуйте эту команду терминала:

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

С здесь

Вот эта команда, обернутая в Какао (которую, вероятно, можно сделать немного чище):

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];
8 голосов
/ 02 апреля 2014

Почему бы не попробовать 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 () возвращает 16-байтовый uuid_t, указанный в id, который однозначно идентифицирует текущий компьютер. Имейте в виду, что идентификаторы оборудования, которые gethostuuid () использует для генерации UUID, могут быть изменены сами.

Аргумент wait - это указатель на struct timepec, которая указывает максимальное время ожидания результата. Установка в ноль полей 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.
8 голосов
/ 17 октября 2009

Было бы проще ответить, если бы вы сказали нам, какой язык вы используете. Информацию можно получить без каких-либо команд оболочки через инфраструктуру 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];
}
5 голосов
/ 20 декабря 2013
/*
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;
}
1 голос
/ 03 июня 2009

Как указали некоторые люди выше, вы можете использовать команду терминала для получения идентификатора оборудования.

Я предполагаю, что вы хотите сделать это в коде, поэтому я бы взглянул на класс NSTask в Какао. Это в основном позволяет вам запускать команды терминала внутри вашего приложения.

Этот код является примером того, как использовать NSTask в Какао. Он устанавливает среду для выполнения команды killall. Он передает это аргумент "Искатель".

Это эквивалентно запуску "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];
1 голос
/ 01 июня 2009

Продолжительность:

system_profiler | grep 'Serial Number (system)'

в терминале возвращает, вероятно, уникальный идентификатор. Это работает на моем 10.5 блоке, я не уверен, какая правильная строка будет в других версиях OS X.

0 голосов
/ 03 июня 2009

System Profiler (в Приложениях - Утилитах) содержит большую часть информации такого рода. Он содержит ваш серийный номер и ваш mac-адрес (не имеет отношения к Mac. У всех компьютеров есть mac-адрес, который практически уникален для каждой сетевой карты).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...