For our licensing / software activation we need to uniquely identify a computer. To do that we're relying on WMI and we're building a unique computer key using BIOS Version, ProcessorID, MainHardDrive serial etc.... It's working great since 4-5 years but we recently have some customers that complains about activation issues.
After some investigations we find that the problem is not new, it exists since the beginning and WMI values seems to be different from an app start to another...
Here is a sample of some customer data that have changed in 2 days :
(on the left "good" data, on the right "inconsistent" empty values)
Sometimes we have users with a corrupted WMI : values are empty or I catch an exception in my code, nothing fancy. In this case a WMI reparation does the job. But it's the first time we're facing inconsistent data...
Thanks for your help !
EDIT : Here's how I retrieve WMI values :
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;
}