我知道stackoverflow中有很多类似的问题,如下所示:
......还有几十个,我研究过它们.
问题是一些已接受的答案已将MAC地址建议为唯一标识符,这完全不正确.其他一些答案建议使用各种组件的组合,这似乎更合乎逻辑.但是,在使用组合的情况下,应该考虑哪些组件自然不可能经常更换.几天前,我们为软件许可问题开发了一个密钥生成器,我们使用CPUID和MAC的组合来唯一地识别一台Windows PC,直到实际测试我们认为我们的方法已经足够好了.具有讽刺意味的是,当我们进行测试时,我们发现有三台计算机使用我们的密钥生
那么,真的有任何方法可以唯一地识别任何计算机吗?现在我们只需要让我们的密钥生成器在windows pc上运行.使用c#的某种方式(如果可能的话)会很好,因为我们的系统是在.net上开发的.
更新:
很抱歉造成一些混乱和明显错误的警报.我们在检索HW信息的方法中发现了一些不正确之处.主要是我想删除这个问题,因为现在我自己的困惑已经消失,我确实认为两个或更多组件的组合足以识别计算机.然而,然后我决定保留它,因为我认为我应该澄清导致问题的原因,因为同样的事情可能会伤害其他人.
这就是我们正在做的事情(不包括其他代码):
我们使用getManagementInfo函数来检索MAC和处理器ID
private String getManagementInfo(String StrKey_String, String strIndex)
{
String strHwInfo = null;
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + StrKey_String);
foreach (ManagementObject share in searcher.Get())
{
strHwInfo += share[strIndex];
}
}
catch (Exception ex)
{
// show some error message
}
return strHwInfo;
}
Run Code Online (Sandbox Code Playgroud)
然后在需要的地方我们使用该函数来检索MAC地址
string strMAC = getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress");
Run Code Online (Sandbox Code Playgroud)
并检索ProcessorID
string strProcessorId = getManagementInfo("Win32_Processor", "ProcessorId");
Run Code Online (Sandbox Code Playgroud)
此时,strMAC …
我即将为我的应用程序实现一个非常基本的许可功能.每台计算机(或每个操作系统)或每个用户可以授予序列号(对于Windows Server中的CAL:如果我的应用程序由一台计算机上的多个用户使用,或者一个用户使用多个用户)机).
对于每个操作系统许可,我用的SerialNumber的Win32_OperatingSystem.
对于每用户许可,我使用:
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
if (currentIdentity != null)
{
SecurityIdentifier userSid = currentIdentity.User.AccountDomainSid;
Console.WriteLine(userSid);
}
Run Code Online (Sandbox Code Playgroud)然后将获得的OS序列号或SID的散列存储在数据库中,与应用程序序列相关联; 每次程序启动时,它都会查询服务器,发送OS SN/SID和应用程序序列的散列.
这样做是对的,还是完全错的?它会在每台Windows机器上运行吗?(例如,使用主板串口是错误的)
我想将程序绑定到特定的计算机,为此我想使用主板的序列号作为唯一标识符。
虽然我可以找到一些 C# 和 Java 的例子,但我找不到任何可靠的 C++(我读过 WMI 可能会因硬件而失败),但肯定有办法在 C++ 中做到这一点吗?
编辑:换句话说,我想要的是一个简单而基本的许可系统。为了更清楚,下面是它的样子:
#define USER_SERIAL 123456789
double GetMotherBoardSerialNumber();
// ...
double currentSerial = GetMotherBoardSerialNumber();
if(currentSerial != USER_SERIAL) {
exit 1;
}
Run Code Online (Sandbox Code Playgroud)
这显然不完美,但我没有任何服务器 atm 来设置帐户系统,因此这可能是一个临时解决方案。
我在 C++ 类中使用 WMI 来检索主板的序列号。查询如下:
"SELECT SerialNumber FROM Win32_BaseBoard"
Run Code Online (Sandbox Code Playgroud)
我自己编写了查询,所以我不确定它是否正确,但它确实返回了一些东西:
/9637CW1/CN1296131Q0BA8/。返回的字符串在多台计算机上采用相同的格式,因此我假设查询是正确的。
我的问题是:我真的在这里查询主板序列号吗?因为我看到另一个类名为"Win32_MotherboardDevice"(它没有“序列号”属性)。使用它作为计算机标识符是个好主意吗?我目前正在使用 HDD 序列号,但我认为使用更可靠的组件(例如主板)的序列号会更好,因为磁盘比主板更容易更换。
谢谢 :)
windows ×3
c# ×2
c++ ×2
wmi ×2
hardware-id ×1
identifier ×1
licensing ×1
motherboard ×1
piracy ×1
winapi ×1