Я знаю, что в stackoverflow есть ряд похожих вопросов, таких как:
- Какой хороший способ однозначно идентифицировать компьютер?
- Что такое хороший уникальный идентификатор ПК?
- Уникальный идентификатор компьютера С#
- WIN32_Processor:: Is ProcessorId уникален для всех компьютеров
- Как однозначно идентифицировать компьютер с помощью С#?
... и еще десятки, и я изучил их все.
Проблема в том, что некоторые из принятых ответов предложили MAC-адрес как уникальный идентификатор, который является полностью неправильным. Некоторые другие ответы предложили использовать комбинацию различных компонентов, что кажется более логичным. Однако в случае использования комбинации следует учитывать, что этот компонент, естественно, вряд ли будет часто изменяться. Несколько дней назад мы разработали ключевой генератор для проблемы лицензирования программного обеспечения, в котором мы использовали комбинацию CPUID и MAC для однозначного определения Windows-ПК, и до практического тестирования мы думали, что наш подход достаточно хорош. По иронии судьбы, когда мы проходили тестирование, мы обнаружили, что три компьютера возвращают один и тот же идентификатор с нашим генератором ключей!
Итак, действительно ли существует какой-либо способ однозначно идентифицировать любой компьютер? Прямо сейчас нам просто нужно заставить наш генератор ключей работать на windows pc. В некотором смысле (если возможно вообще) с использованием С# было бы здорово, так как наша система была разработана на .net.
Update:
Извините за создание путаницы и, по-видимому, ложную тревогу. Мы обнаружили некорректность в нашем методе получения 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
.
Следующий код 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-адресом. Я думаю, что наша цель будет удовлетворена таким образом, и если это не будет в некоторых случаях, тогда мы должны разрешить это в тех немногих случаях.