¿Existe realmente alguna forma de identificar de manera única cualquier computadora?

Sé que hay una serie de preguntas similares en stackoverflow, como las siguientes:

¿Cuál es una buena manera de identificar de manera única una computadora? ¿Cuál es un buen identificador de PC único? Identificación única de la computadora C # WIN32_Processor :: Es ProcessorId único para todas las computadoras ¿Cómo identificar de manera única la computadora usando C #?

... y docenas más y los he estudiado a todos.

El problema es que algunas de las respuestas aceptadas han sugerido la dirección MAC como un identificador único que es completamente incorrecto. Algunas otras respuestas han sugerido usar una combinación de varios componentes que parece más lógico. Sin embargo, en caso de utilizar una combinación, se debe considerar qué componente es naturalmente poco probable que se cambie con frecuencia. Hace unos días desarrollamos un generador de claves para un problema de licencia de software en el que utilizamos la combinación de CPUID y MAC para identificar un PC con Windows de forma exclusiva y hasta las pruebas prácticas pensamos que nuestro enfoque era lo suficientemente bueno. ¡Irónicamente, cuando lo probamos, encontramos tres computadoras que devolvían la misma identificación con nuestro generador de claves!

Entonces, ¿hay realmente alguna forma de identificar de manera única cualquier computadora? En este momento solo necesitamos hacer que nuestro generador de claves funcione en Windows PC. De alguna manera (si es posible) usar c # sería genial ya que nuestro sistema está desarrollado en .net.

Actualizar

Lo siento por crear algunas confusiones y una alarma aparentemente falsa. Descubrimos algunas incorrecciones en nuestro método de recuperación de información de HW. Principalmente pensé en eliminar esta pregunta porque ahora mi propia confusión se ha ido y creo que una combinación de dos o más componentes es lo suficientemente buena como para identificar una computadora. Sin embargo, decidí mantenerlo porque creo que debería aclarar qué estaba causando el problema, ya que lo mismo podría lastimar a otro tipo en el futuro.

Esto es lo que estábamos haciendo (excluyendo otros códigos):

Estábamos usando unagetManagementInfo función para recuperar MAC e ID de procesador

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

uego, cuando fue necesario, usamos esa función para recuperar la dirección MAC

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

y para recuperar ProcessorID

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

En este punto,strMAC contendría más de una dirección MAC si hay más de una. Para tomar solo uno, solo tomamos los primeros 17 caracteres (12 dígitos MAC y 5 puntos intermedios).

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

Aquí es donde cometimos el error. PorquegetManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress") estaba devolviendo una cantidad de direcciones MAC adicionales que realmente estaban en uso. Por ejemplo, cuando buscamos direcciones MAC en el símbolo del sistema porgetmac comando luego mostró una o dos direcciones MAC para cada PC que eran todas diferentes. PerogetManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress") devolvió de cuatro a cinco direcciones MAC, algunas de las cuales eran idénticas para todas las computadoras. Como acabamos de tomar la primera dirección MAC que devolvió nuestra función en lugar de verificar cualquier otra cosa, se tomaron las direcciones MAC idénticas enstrMAC incidentemente.

El siguiente código deSowkot Osman hace el truco devolviendo solo la primera dirección MAC activa / habilitada:

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

Sin embargo, tenía toda la razón sobre el problema de ID de procesador idéntico. Los tres devolvieron la misma ID de procesador cuando pusimoswmic cpu get ProcessorId comando en sus indicaciones de comando.

Ahora hemos decidido utilizar el número de serie de la placa base en lugar de la ID del procesador para hacer una combinación con la dirección MAC. Creo que nuestro propósito se cumplirá de esta manera y si no lo hace en algunos casos, deberíamos dejarlo ir en esos pocos casos.

Respuestas a la pregunta(8)

Su respuesta a la pregunta