Я знаю, что в стеке потока есть ряд похожих вопросов, таких как:
... и еще десятки, и я изучил их все.
Проблема в том, что некоторые из принятых ответов предложили 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;
}
Затем, при необходимости, мы использовали эту функцию для получения 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
.
Следующий код Sowkot Osman добивается цели, возвращая только первый активный / включенный 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-адресом. Я думаю, что наша цель будет достигнута таким образом, и если в некоторых случаях этого не произойдет, то мы должны отпустить ее в этих нескольких случаях.