对于我们的许可/软件激活,我们需要唯一标识一台计算机。为此,我们依赖于 WMI,并且我们正在使用 BIOS 版本、处理器 ID、MainHardDrive 序列等构建一个独特的计算机密钥。自 4 到 5 年以来它一直运行良好,但我们最近有一些客户抱怨激活问题.
经过一些调查,我们发现问题不是新问题,它从一开始就存在,并且 WMI 值似乎从一个应用程序开始到另一个不同......
以下是 2 天内发生变化的一些客户数据示例:
(左侧“好”数据,右侧“不一致”空值)
有时我们的用户的 WMI 已损坏:值是空的,或者我在代码中发现了异常,没什么特别的。在这种情况下,WMI 修复可以完成这项工作。但这是我们第一次面对不一致的数据......
谢谢你的帮助 !
编辑:这是我检索 WMI 值的方法:
private static Dictionary<string, string> GetBiosInfo()
{
Dictionary<string, object> classIdentifiers = GetIdentifiers("Win32_BIOS");
Dictionary<string, string> biosInfo = new Dictionary<string, string>
{
{ BiosInfo_Manufacturer, GetIdentifier(classIdentifiers, "Manufacturer") },
{ BiosInfo_SMBIOSBIOSVersion, GetIdentifier(classIdentifiers, "SMBIOSBIOSVersion") },
{ BiosInfo_IdentificationCode, GetIdentifier(classIdentifiers, "IdentificationCode") },
{ BiosInfo_SerialNumber, GetIdentifier(classIdentifiers, "SerialNumber") },
{ BiosInfo_ReleaseDate, GetIdentifier(classIdentifiers, "ReleaseDate") },
{ BiosInfo_Version, GetIdentifier(classIdentifiers, "Version") }
};
return new Dictionary<string, string>(biosInfo);
}
private static Dictionary<string, object> GetIdentifiers(string wmiClass, int tryNumber = 0)
{
if (tryNumber == 0)
{
_timers.Add(wmiClass, DateTime.Now);
}
try
{
ManagementClass mc = new ManagementClass(wmiClass);
ManagementObjectCollection moc = mc.GetInstances();
Dictionary<string, object> values = new Dictionary<string, object>();
foreach (var mo in moc)
{
foreach (var item in mo.Properties)
{
if (!values.ContainsKey(item.Name))
{
values.Add(item.Name, item.Value);
}
}
foreach (var item in mo.SystemProperties)
{
if (!values.ContainsKey(item.Name))
{
values.Add(item.Name, item.Value);
}
}
}
return values;
}
catch (Exception e)
{
if (tryNumber <= 200)
{
tryNumber = tryNumber + 1;
return GetIdentifiers(wmiClass, tryNumber);
}
else
{
// Si après 200 essais on arrive toujours pas à obtenir les informations on laisse tomber
// on crée une exception spécifique
GetIdentifiersException newException = new GetIdentifiersException(string.Format("Erreur interne dans la méthode SystemHelper.GetIdentifiers (appel de la méthode GetInstances)... / WMIClass : {0} / Essai n°{1} / Durée : {2} ms", wmiClass, tryNumber, (DateTime.Now - _timers[wmiClass]).TotalMilliseconds), e);
// on renvoi l'exception pour l'attraper dans la classe appelante (VBActivation)
throw newException;
}
}
}
private static string GetIdentifier(Dictionary<string, object> classIdentifiers, string wmiProperty)
{
string result = string.Empty;
if (classIdentifiers != null && classIdentifiers.ContainsKey(wmiProperty))
{
result = classIdentifiers[wmiProperty] != null ? classIdentifiers[wmiProperty].ToString() : string.Empty;
}
return result;
}