Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 真的有什么方法可以唯一地识别任何一台计算机吗_C#_Windows_Uniqueidentifier - Fatal编程技术网

C# 真的有什么方法可以唯一地识别任何一台计算机吗

C# 真的有什么方法可以唯一地识别任何一台计算机吗,c#,windows,uniqueidentifier,C#,Windows,Uniqueidentifier,我知道stackoverflow中有许多类似的问题,例如: 。。。还有几十个,我都研究过了 问题是,一些公认的答案建议将MAC地址作为唯一标识符,这是完全不正确的。其他一些答案建议使用各种组件的组合,这似乎更符合逻辑。但是,在使用组合的情况下,应考虑自然不太可能频繁更换的组件。几天前,我们为一个软件许可问题开发了一个密钥生成器,我们使用CPUID和MAC的组合来唯一地识别一台windows pc,在实际测试之前,我们认为我们的方法已经足够好了。具有讽刺意味的是,当我们去测试它时,我

我知道stackoverflow中有许多类似的问题,例如:

。。。还有几十个,我都研究过了

问题是,一些公认的答案建议将MAC地址作为唯一标识符,这是完全不正确的。其他一些答案建议使用各种组件的组合,这似乎更符合逻辑。但是,在使用组合的情况下,应考虑自然不太可能频繁更换的组件。几天前,我们为一个软件许可问题开发了一个密钥生成器,我们使用CPUID和MAC的组合来唯一地识别一台windows pc,在实际测试之前,我们认为我们的方法已经足够好了。具有讽刺意味的是,当我们去测试它时,我们发现三台计算机返回与我们的密钥生成器相同的id

那么,真的有什么方法可以唯一地识别任何一台计算机吗?现在,我们只需要让我们的密钥生成器在windows pc上工作。使用c#的某种方式(如果可能的话)会很好,因为我们的系统是在.net上开发的

更新:

很抱歉造成了一些混乱和明显的错误警报。我们发现我们检索硬件信息的方法有一些不正确之处。我最初想删除这个问题,因为现在我自己的困惑已经消失了,我相信两个或更多组件的组合足以识别计算机。然而,后来我决定保留它,因为我认为我应该澄清是什么导致了这个问题,因为同样的事情可能会伤害到其他人

这就是我们正在做的(不包括其他代码):

我们使用
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;
    } 
然后在需要的地方,我们使用该函数检索MAC地址

string strMAC = getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress");
和检索ProcessorID

string strProcessorId = getManagementInfo("Win32_Processor", "ProcessorId");
此时,如果存在多个MAC地址,
strMAC
将包含多个MAC地址。为了只取一个,我们只取了前17个字符(12个MAC数字,中间有5个冒号)

这就是我们犯错误的地方。因为
getManagementInfo(“Win32\U NetworkAdapterConfiguration”,“MacAddress”)
返回了大量实际使用的额外MAC地址。例如,当我们在命令提示符下通过
getmac
命令搜索MAC地址时,它会显示每台电脑的一个或两个MAC地址,这些地址都是不同的。但是
getManagementInfo(“Win32\U NetworkAdapterConfiguration”,“MacAddress”)
返回了四到五个MAC地址,其中一些对于所有计算机都是相同的。由于我们只是获取函数返回的第一个MAC地址,而没有检查任何其他内容,因此顺便在
strMAC
中获取了相同的MAC地址

下面的代码通过只返回第一个活动/启用的MAC地址来实现此目的:

private static string macId()
    {
        return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
    }

private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            if (mo[wmiMustBeTrue].ToString() == "True")
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
        }
        return result;
    }
    //Return a hardware identifier
    private static string identifier(string wmiClass, string wmiProperty)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            //Only get the first one
            if (result == "")
            {
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
        }
        return result;
    }
然而,关于相同的处理器ID问题,我是绝对正确的。当我们将
wmic cpu get ProcessorId
命令放入它们的命令提示符中时,这三个命令都返回了相同的处理器ID


现在我们决定使用主板序列号而不是处理器ID来与MAC地址进行组合。我认为这样做可以达到我们的目的,如果在某些情况下不能达到目的,那么在少数情况下我们应该放弃它。

添加主板序列号怎么样,例如:

using System.management;


//Code for retrieving motherboard's serial number
ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32_BaseBoard");
foreach (ManagementObject getserial in MOS.Get())
{
textBox1.Text = getserial["SerialNumber"].ToString();
}

//Code for retrieving Processor's Identity
MOS = new ManagementObjectSearcher("Select * From Win32_processor");
foreach (ManagementObject getPID in MOS.Get())
{
textBox2.Text = getPID["ProcessorID"].ToString();
}

//Code for retrieving Network Adapter Configuration
MOS = new ManagementObjectSearcher("Select * From Win32_NetworkAdapterConfiguration");
foreach (ManagementObject mac in MOS.Get())
{
textBox3.Text = mac["MACAddress"].ToString();
}

获得全局唯一ID的事实是,只有MAC地址是不会更改的ID,如果您在整个系统中进行设置。如果要为特定产品生成密钥,最好的方法是为产品分配唯一ID,并将产品ID与MAC地址相结合。希望能有帮助

我完全同意上述评论

对于软件许可,您可以使用:

计算机MAC地址(如果有多个NIC卡,则全部使用)+您的软件产品代码

大多数著名的电信供应商都在使用这种技术

然而,关于相同的处理器ID,我是绝对正确的 问题当我们放入wmic cpu时,这三个都返回了相同的处理器ID 在命令提示中获取ProcessorId命令

如果所有系统都作为虚拟机在同一虚拟机监控程序上运行,则处理器ID将相同


MAC ID看起来不错。唯一的问题是,如果MAC电脑发生变化,必须向用户提供重置应用程序的选项。

看来定制厨房就是解决这个问题的方法

SMBIOS UUID(主板串行)不稳定,但在99%的情况下工作正常。但是,一些品牌会为多台计算机设置相同的UUID(可能是同一生产批次)。获取它需要用户(如果他不是管理员)具有WMI访问权限,您可以通过启动一个请求管理员权限的外部进程来解决这一问题(检查codeproject.com/Articles/15848/WMI命名空间安全性)

Windows产品ID可能不错,但我读到它在某些情况下可能是相同的() 有人能澄清一下,在多台计算机上是否存在相同的产品ID(不是产品密钥)

HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid似乎很有趣。它是在安装Windows时生成的,如果更改,则需要重新激活Windows

Mac地址是相互测试的,但您只能使用第一个地址,否则当接口被禁用时,或者当添加另一个网络接口并首先显示时,您的唯一ID将发生更改,等等

硬盘驱动器序列号很好,但在安装ghost时,它也可能会覆盖原始驱动器的序列号。。。而且HD系列非常容易更换

最好是使用这些机器标识符的组合生成一个ID,并通过比较这些标识符来确定机器是否相同(即,如果至少有一个Mac地址+SMBIOS UUID或产品ID正常,则接受)

simp
using System.management;


//Code for retrieving motherboard's serial number
ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32_BaseBoard");
foreach (ManagementObject getserial in MOS.Get())
{
textBox1.Text = getserial["SerialNumber"].ToString();
}

//Code for retrieving Processor's Identity
MOS = new ManagementObjectSearcher("Select * From Win32_processor");
foreach (ManagementObject getPID in MOS.Get())
{
textBox2.Text = getPID["ProcessorID"].ToString();
}

//Code for retrieving Network Adapter Configuration
MOS = new ManagementObjectSearcher("Select * From Win32_NetworkAdapterConfiguration");
foreach (ManagementObject mac in MOS.Get())
{
textBox3.Text = mac["MACAddress"].ToString();
}