Есть ли вообще какой-либо способ однозначно идентифицировать любой компьютер

Я знаю, что в stackoverflow есть ряд аналогичных вопросов, таких как следующие:

... и многие другие, и я изучил их все.

Проблема в том, что в некоторых из принятых ответов в качестве уникального идентификатора предлагался MAC-адрес, что совершенно неверно. В некоторых других ответах предлагалось использовать комбинацию различных компонентов, что кажется более логичным. Однако в случае использования комбинации следует учитывать, какой компонент, естественно, вряд ли будет часто заменяться. Несколько дней назад мы разработали генератор ключей для решения проблемы лицензирования программного обеспечения, в котором мы использовали комбинацию CPUID и MAC для однозначной идентификации ПК с Windows, и до практических испытаний мы думали, что наш подход достаточно хорош. По иронии судьбы, когда мы начали его тестировать, мы обнаружили три компьютера, возвращающих один и тот же идентификатор с нашим генератором ключей!

Итак, есть ли вообще какой-нибудь способ однозначно идентифицировать любой компьютер? Сейчас нам просто нужно заставить наш генератор ключей работать на ПК с Windows. Каким-то образом (если вообще возможно) использование C # было бы замечательно, поскольку наша система разработана на .net.

Обновление:

Извините за путаницу и заведомо ложную тревогу. Мы обнаружили некоторую некорректность в нашем методе получения информации об HW. В первую очередь я подумал об удалении этого вопроса, так как теперь моя собственная путаница исчезла, и я действительно считаю, что комбинация двух или более компонентов достаточно хороша для идентификации компьютера. Однако затем я решил сохранить это, потому что я думаю, что должен уточнить, что было причиной проблемы, поскольку то же самое может навредить другому парню в будущем.

Это то, что мы делали (исключая другие коды):

Мы использовали функцию getManagementInfo для получения MAC-адреса и идентификатора процессора

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");

На этом этапе strMAC будет содержать более одного MAC-адреса, если их больше одного. Чтобы взять только один, мы просто взяли первые 17 символов (12 цифр MAC и 5 двоеточий между ними).

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

Вот где мы допустили ошибку. Поскольку getManagementInfo ("Win32_NetworkAdapterConfiguration", "MacAddress") возвращал ряд дополнительных MAC-адресов, которые действительно использовались. Например, когда мы искали MAC-адреса в командной строке с помощью команды getmac , то показывались один или два MAC-адреса для каждого компьютера, которые все были разными. Но getManagementInfo ("Win32_NetworkAdapterConfiguration", "MacAddress") вернул от четырех до пяти MAC-адресов, некоторые из которых были идентичны для всех компьютеров. Поскольку мы просто взяли первый MAC-адрес, который вернула наша функция, вместо проверки чего-либо еще, идентичные MAC-адреса были случайно взяты в strMAC .

Следующий код от Соукота Османа помогает добиться цели, возвращая только первый активный / активный 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;
    }

Однако я был абсолютно прав насчет идентичной проблемы с идентификатором процессора. Все трое вернули один и тот же идентификатор процессора, когда мы поместили команду wmic cpu get ProcessorId в их командные строки.

Теперь мы решили использовать серийный номер материнской платы вместо идентификатора процессора для совмещения с MAC-адресом. Я думаю, что таким образом наша цель будет достигнута, и если в некоторых случаях этого не произойдет, то в этих нескольких случаях мы должны отпустить ее.

30
задан Community 23 May 2017 в 11:54
поделиться