Existe realmente alguma maneira de identificar exclusivamente qualquer computador

Sei que há várias perguntas semelhantes no stackoverflow, como as seguintes:

Qual é uma boa maneira de identificar exclusivamente um computador?O que é um bom identificador único de PC? ID de computador exclusivo C # WIN32_Processor :: ProcessorId é exclusivo para todos os computadoresComo identificar exclusivamente o computador usando C #?

... e dezenas de outras e eu estudei todas ela

O problema é que algumas das respostas aceitas sugeriram o endereço MAC como um identificador exclusivo que está totalmente incorreto. Algumas outras respostas sugeriram o uso de uma combinação de vários componentes que parece mais lógico. No entanto, no caso de usar uma combinação, deve-se considerar qual componente é naturalmente improvável de ser alterado frequentemente. Alguns dias atrás, desenvolvemos um gerador de chaves para um problema de licenciamento de software em que usamos a combinação de CPUID e MAC para identificar um PC com Windows de forma exclusiva e, até testes práticos, achamos que nossa abordagem era boa o suficiente. Ironicamente, quando o testamos, encontramos três computadores retornando o mesmo ID com nosso gerador de chaves!

Então, existe realmente alguma maneira de identificar algum computador de maneira única? No momento, precisamos apenas fazer nosso gerador de chaves funcionar no Windows PC. De alguma forma (se possível), usar c # seria ótimo, pois nosso sistema é desenvolvido em .net.

Atualizar

Desculpe por criar algumas confusões e um alarme aparentemente falso. Descobrimos algumas incorreções em nosso método de recuperar informações de HW. Primeiramente, pensei em excluir essa pergunta, pois agora minha própria confusão se foi e acredito que uma combinação de dois ou mais componentes é suficiente para identificar um computador. No entanto, decidi mantê-lo porque acho que deveria esclarecer o que estava causando o problema, pois a mesma coisa pode machucar outro cara no futur

Isto é o que estávamos fazendo (excluindo outros códigos):

Nós estávamos usando umgetManagementInfo para recuperar o MAC e o ID do processador

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;
    } 

Em seguida, quando necessário, usamos essa função para recuperar o endereço MAC

string strMAC = getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress");

e para recuperar ProcessorID

string strProcessorId = getManagementInfo("Win32_Processor", "ProcessorId");

Neste ponto,strMAC conteria mais de um endereço MAC, se houver mais de um. Para pegar apenas um, pegamos apenas os primeiros 17 caracteres (12 dígitos MAC e 5 dois pontos no meio

strMAC = strMAC.Length > 17 ? strMAC.Remove(17) : strMAC;

Foi aqui que cometemos o erro. PorquegetManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress") estava retornando vários endereços MAC extras que estavam realmente em uso. Por exemplo, quando procuramos endereços MAC no prompt de comando porgetmac, então ele mostrou um ou dois endereços MAC para cada PC, todos diferentes. MasgetManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress") retornou de quatro a cinco endereços MAC, alguns dos quais eram idênticos para todos os computadores. Como acabamos de pegar o primeiro endereço MAC que nossa função retornou em vez de verificar qualquer outra coisa, os endereços MAC idênticos foram obtidos emstrMAC incidentalmente.

O código a seguir porSowkot Osman faz o truque retornando apenas o primeiro endereço MAC ativo / ativado:

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;
    }

No entanto, eu estava absolutamente certo sobre o mesmo problema de identificação do processador. Todos os três retornaram o mesmo ID do processador quando colocamoswmic cpu get ProcessorId em seus prompts de comand

gora decidimos usar o número de série da placa-mãe em vez da identificação do processador para fazer uma combinação com o endereço MAC. Acho que nosso objetivo será atendido dessa maneira e, se isso não acontecer, em alguns casos, devemos deixá-lo ir nesses poucos caso