有没有办法限制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);
}
}
}
答案 0 :(得分:4)
一个选项是使用WHERE
子句指定所需条目的范围......
例如,您可以在WHERE
子句中使用TimeGenerated
来指定基于时间的范围......
另一个选择是在创建BlockSize
时相应地设置ManagementObjectSearcher
。
您可以使用它来指定每次调用需要2000个条目 - 与ORDER BY TimeGenerated DESC
一起使用这应该会产生一个不错的结果。
答案 1 :(得分:1)
速度并不适合WMI。它往往是相当大的内存密集型。但是,问题已得到解决,您可以做一些事情。从Microsoft TechNet查看Why are my queries taking such a long time to complete?。
答案 2 :(得分:0)
现在使用System.Diagnostics.EventLog类作为更快的替代方法。与WMI相比,该计划更有益。
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx