C++ Mac OS X 中的唯一硬件 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/933460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unique hardware ID in Mac OS X
提问by Gerald
Mac OS X development is a fairly new animal for me, and I'm in the process of porting over some software. For software licensing and registration I need to be able to generate some kind of hardware ID. It doesn't have to be anything fancy; Ethernet MAC address, hard drive serial, CPU serial, something like that.
Mac OS X 开发对我来说是一个相当新的动物,我正在移植一些软件。对于软件许可和注册,我需要能够生成某种硬件 ID。它不必是任何花哨的东西;以太网 MAC 地址、硬盘串行、CPU 串行等等。
I've got it covered on Windows, but I haven't a clue on Mac. Any idea of what I need to do, or where I can go for information on this would be great!
我已经在 Windows 上覆盖了它,但在 Mac 上我没有任何线索。任何我需要做什么的想法,或者我可以去哪里了解这方面的信息都会很棒!
Edit:
编辑:
For anybody else that is interested in this, this is the code I ended up using with Qt's QProcess class:
对于对此感兴趣的其他任何人,这是我最终在 Qt 的 QProcess 类中使用的代码:
QProcess proc;
QStringList args;
args << "-c" << "ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { print ; }'";
proc.start( "/bin/bash", args );
proc.waitForFinished();
QString uID = proc.readAll();
Note: I'm using C++.
注意:我使用的是 C++。
采纳答案by xyz
Try this Terminal command:
试试这个终端命令:
ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split(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(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);
}
, 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];
, line, "\""); printf("%s\n", line[4]); }'
From here
从这里
Here is that command wrapped in Cocoa (which could probably be made a bit cleaner):
这是用 Cocoa 包装的命令(可能会更简洁一些):
gethostuuid -- return a unique identifier for the current machine
回答by yairchu
For C/C++:
对于 C/C++:
#include <unistd.h>
int gethostuuid(uuid_t id, const struct timespec *wait);
回答by zhanglin
Why not try gethostuuid()
? Here's the documentation from the Mac OS X System Calls Manual:
为什么不试试gethostuuid()
?这是 Mac OS X 系统调用手册中的文档:
NAME:
姓名:
[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.
SYNOPSIS:
概要:
- (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];
}
DESCRIPTION:
描述:
The gethostuuid() function returns a 16-byte uuid_t specified by id, that uniquely identifies the current machine. Be aware that the hardware identifiers that gethostuuid() uses to generate the UUID can themselves be modified.
The wait argument is a pointer to a struct timespec that specifies the maximum time to wait for the result. Setting the tv_sec and tv_nsec fields to zero means to wait indefinitely until it completes.
gethostuuid() 函数返回一个由 id 指定的 16 字节 uuid_t,它唯一标识当前机器。请注意,gethostuuid() 用于生成 UUID 的硬件标识符本身可以修改。
wait 参数是一个指向结构 timespec 的指针,该结构指定等待结果的最长时间。将 tv_sec 和 tv_nsec 字段设置为零意味着无限期地等待直到它完成。
RETURN VALUES:
返回值:
The gethostuuid() function returns zero on success or -1 on error.
gethostuuid() 函数在成功时返回零或在错误时返回 -1。
ERRORS
错误
The gethostuuid() functions fails if:
如果出现以下情况,gethostuuid() 函数将失败:
/*
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;
}
回答by Azeem.Butt
This would be easier to answer if you told us what language you were using. The information is obtainable without any shell commands through the SystemConfiguration framework, and also through IOKit if you want to get your hands really dirty.
如果您告诉我们您使用的是哪种语言,这将更容易回答。这些信息无需任何 shell 命令即可通过 SystemConfiguration 框架获得,如果您想真正弄脏手,也可以通过 IOKit 获得。
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];
回答by Nitinkumar Ambekar
system_profiler | grep 'Serial Number (system)'
回答by Brock Woolf
As some people above have hinted, you can use a Terminal command to get a hardware ID.
正如上面的一些人所暗示的,您可以使用终端命令来获取硬件 ID。
I assume you want to do this in code however so I would take a look at the NSTask class in Cocoa. It basically lets you run terminal commands inside your application.
我假设您想在代码中执行此操作,因此我将查看 Cocoa 中的 NSTask 类。它基本上允许您在应用程序中运行终端命令。
This code is an example of how to use NSTask in Cocoa. It sets up the environment to execute the "killall" command. It passes it the arguement "Finder".
此代码是如何在 Cocoa 中使用 NSTask 的示例。它设置了执行“killall”命令的环境。它通过了争论“Finder”。
It's the equivilent of running "killall Finder" on the command line, which will kill the Finder obviously.
这相当于在命令行上运行“killall Finder”,这显然会杀死 Finder。
##代码##回答by kbyrd
Running:
跑步:
##代码##in a terminal returns what it likely a unique id. That works on my 10.5 box, I'm not sure what the correct string will be in other versions of OS X.
在终端中返回它可能是唯一的 id。这适用于我的 10.5 机器,我不确定在其他版本的 OS X 中正确的字符串是什么。
回答by Singletoned
System Profiler (in Applications - Utilities) contains most of this kind of info. It has your serial number and your mac address (no relation to Mac. All computers have a mac address which is pretty much unique to every network card).
System Profiler(在应用程序 - 实用程序中)包含大部分此类信息。它有您的序列号和您的 mac 地址(与 Mac 无关。所有计算机都有一个几乎每个网卡唯一的 mac 地址)。