Уникальный идентификатор оборудования в Mac OS X
-
06-09-2019 - |
Вопрос
Разработка Mac OS X для меня довольно новая задача, и я сейчас занимаюсь переносом некоторого программного обеспечения.Для лицензирования и регистрации программного обеспечения мне нужно иметь возможность сгенерировать какой-то идентификатор оборудования.Это не обязательно должно быть что-то необычное;MAC-адрес Ethernet, серийный номер жесткого диска, серийный номер процессора и что-то в этом роде.
Я разобрался с этим в Windows, но понятия не имею о Mac.Любая идея о том, что мне нужно сделать или куда я могу обратиться за информацией по этому поводу, была бы замечательной!
Редактировать:
Для всех, кого это интересует, вот код, который я использовал с классом QProcess 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();
Примечание:Я использую С++.
Решение
Попробуйте эту команду терминала:
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];
Другие советы
Для Си/С++:
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);
}
Почему бы не попробовать 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, указанный идентификатором, который однозначно идентифицирует текущий компьютер.Имейте в виду, что идентификаторы оборудования, которые gethostuuid() использует для генерации UUID, сами по себе могут быть изменены.
Аргумент ожидания — это указатель на структуру 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.
Было бы легче ответить, если бы вы сказали нам, на каком языке вы говорите.Информацию можно получить без каких-либо команд оболочки через структуру 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];
}
/*
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;
}
Бег:
system_profiler | grep 'Serial Number (system)'
в терминале возвращает, вероятно, уникальный идентификатор.Это работает на моем компьютере 10.5, я не уверен, какой будет правильная строка в других версиях OS X.
Как намекали некоторые люди выше, вы можете использовать команду Терминала, чтобы получить идентификатор оборудования.
Однако я предполагаю, что вы хотите сделать это в коде, поэтому я хотел бы взглянуть на класс NSTask в Cocoa.По сути, он позволяет запускать команды терминала внутри вашего приложения.
Этот код является примером использования NSTask в Cocoa.Он настраивает среду для выполнения команды «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];
Профилировщик системы (в разделе «Приложения» — «Утилиты») содержит большую часть такой информации.Он содержит ваш серийный номер и ваш Mac-адрес (не имеет отношения к Mac.Все компьютеры имеют MAC-адрес, который практически уникален для каждой сетевой карты).