Значения WMI кажутся противоречивыми - PullRequest
0 голосов
/ 18 февраля 2020

Для нашей лицензии / активации программного обеспечения нам необходимо однозначно идентифицировать компьютер. Для этого мы полагаемся на WMI и создаем уникальный ключ компьютера, используя B IOS Version, ProcessorID, MainHardDrive serial et c .... Он отлично работает с 4-5 лет, но недавно у нас были некоторые клиенты, которые жалуются на проблемы с активацией.

После некоторых исследований мы обнаруживаем, что проблема не нова, она существует, поскольку начало и значения WMI отличаются от запуска приложения к другому ...

Вот пример некоторых данных клиентов, которые изменились за 2 дня:

wmi values differences

(слева "хорошие" данные, справа «несогласованные» пустые значения)

Иногда у нас есть пользователи с поврежденным 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;
}
...