WMI работает слишком медленно - PullRequest
3 голосов
/ 01 апреля 2012

Есть ли способ ограничить количество записей, извлекаемых WMI с помощью оператора WQL? Я говорю это потому, что выполнение запроса для извлечения всех экземпляров Win32_NTLogEvent занимает вечно! Все, что мне действительно нужно, это самые последние события (около недели или 2000 записей)

Вот фрагмент кода, который я использую для получения данных журнала. Другие запросы, такие как Win32_Processor, хороши и быстры.

            if (Configuration.OnlyErrorLogs)
            {
                // If Information logs should be suppressed, only get events where event type is not 3
                WMIDataTemp1 = DataRetriever.GetWMIData("Win32_NTLogEvent", "EventType<>3");
            }
            else
            {
                WMIDataTemp1 = DataRetriever.GetWMIData("Win32_NTLogEvent");
            }
            foreach (ManagementObject Object in WMIDataTemp1)
            {
                this.Log.Add(new Log(Object));
            }

А функции для получения данных WMI следующие:

    public static ManagementObject[] GetWMIData(string wmiClass) { return GetWMIData(wmiClass, "", "CIMV2"); }
    public static ManagementObject[] GetWMIData(string wmiClass, string whereClause) { return GetWMIData(wmiClass, whereClause, "CIMV2"); }
    public static ManagementObject[] GetWMIData(string wmiClass, string whereClause, string nameSpace)
    {
        try
        {
            // If a where clause has been set, prepare the clause to add to the query string
            if (whereClause != "")
            {
                whereClause = " WHERE " + whereClause;
            }
            // Create a search query
            string query = "SELECT * FROM " + wmiClass + whereClause;
            ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("root\\" + nameSpace, query);
            ManagementObjectCollection matches = wmiSearcher.Get();

            // Create an array to hold the matches
            ManagementObject[] matchArray = new ManagementObject[matches.Count];

            // If matches found, copy to output
            if(matches.Count > 0)
            {
                // Copy the search matches into this array
                matches.CopyTo(matchArray, 0);
            }

            // Return array
            return matchArray;
        }
        catch (Exception e)
        {
            ErrorDialogue errorReporter = new ErrorDialogue(e);
            return null;
        }
    }

Где хранится каждый журнал:

public class Log
{
    public string Category = "N/A";
    public string DateTime = "N/A";
    public UInt16 ID = 0;
    public string Level = "N/A";
    public string Message = "N/A";
    public string Source = "N/A";

    public Log() { }
    public Log(ManagementObject wmiLogEvent)
    {
        this.GetInfo(wmiLogEvent);
    }

    public void GetInfo(ManagementObject wmiLogEvent)
    {
        try
        {
            this.Category = DataRetriever.GetValue(wmiLogEvent, "CategoryString");
            this.DateTime = DataRetriever.GetValue(wmiLogEvent, "TimeGenerated");
            this.ID = DataRetriever.GetValueUInt16(wmiLogEvent, "EventIdentifier");
            this.Level = DataRetriever.ConvertEventType(DataRetriever.GetValueUInt16(wmiLogEvent, "CategoryString"));
            this.Message = DataRetriever.GetValue(wmiLogEvent, "Message");
            this.Source = DataRetriever.GetValue(wmiLogEvent, "SourceName");
        }
        catch (Exception e)
        {
            ErrorDialogue errorReporter = new ErrorDialogue(e);
        }
    }
}

Ответы [ 3 ]

4 голосов
/ 01 апреля 2012

Одним из вариантов является использование предложения WHERE для указания диапазона желаемых записей ...

Например, вы можете использовать TimeGenerated в предложении WHERE, чтобы указать временной диапазон ...

Другим вариантом является установка BlockSize соответственно при создании ManagementObjectSearcher.

Вы можете использовать это, чтобы указать, что вы хотите, например, 2000 записей на вызов - вместе с ORDER BY TimeGenerated DESC это должно дать хороший результат.

1 голос
/ 02 апреля 2012

Скорость не является сильной стороной для WMI. Это имеет тенденцию быть довольно интенсивным объемом памяти. Тем не менее, вопрос был решен, и вы можете сделать несколько вещей. Проверьте Почему мои запросы занимают так много времени? от Microsoft TechNet.

0 голосов
/ 02 мая 2012

Теперь используем класс System.Diagnostics.EventLog в качестве более быстрой альтернативы.Гораздо полезнее для программы по сравнению с WMI.

http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...