public List <EventLogRecord> Retrieve() { List <EventLogRecord> records = new List <EventLogRecord>(); WMIRetrieverOptions options = new WMIRetrieverOptions(); WMIRetriever retriever = new WMIRetriever(Context, options); Stopwatch watch = Stopwatch.StartNew(); WMIRetriever.RetrievalContext retrieval_context = retriever.Retrieve(null); long retrieval = watch.ElapsedMilliseconds; watch.Restart(); if (retrieval_context != null) { lock (retrieval_context.RetrievedData) { retrieval_context.RetrievedData.ForEach(r => { try { records.Add(new EventLogRecord(r)); } catch (Exception) { } }); } } //ApplicationEventLog log = new ApplicationEventLog(); //log.LogInformation($"GenericEventLogCollector: retrieval took {retrieval} ms and building list took {watch.ElapsedMilliseconds} ms for {records.Count} records"); return(records); }
protected virtual void OnAcquireDelegate(OnProperty on_property) { WMIRetriever retriever = new WMIRetriever(WmiContext, RetrieverOptions); WMIRetriever.RetrievalContext retrieval_context = retriever.Retrieve(m_log); if (retrieval_context != null) { retrieval_context.RetrievedData.ForEach(r => on_property(r)); } }
public override CollectedData OnAcquire() { // The number of cores will be different for each of the devices that we monitor, so we have to get this // inside each RunningProcessesData object, not globally. But at least it won't change so we can just get it once. if (m_cores == 0) { WMIRetriever retriever = new WMIRetriever(new WMIContext("Win32_Processor", "NumberOfCores", WmiContext.RemoteInfo), new WMIRetrieverOptions()); WMIRetriever.RetrievalContext retrieval_context = retriever.Retrieve(null); if (retrieval_context != null && retrieval_context.RetrievedData.Count > 0) { Dictionary <string, object> r = retrieval_context.RetrievedData[0]; uint.TryParse(r["NumberOfCores"].ToString(), out m_cores); } } if (m_cores == 0) { throw new Exception("Unable to determine the # of cores on the machine"); } Dictionary <string, Process> collected_data = new Dictionary <string, Process>(); // We do this twice...I found that sometimes the first time we'd try and get the data we'd get nothing, // but the second attempt would work. Go figure. OnAcquireDelegate(dict => { }); OnAcquireDelegate( dict => { string name = dict["Name"].ToString(); string percent_processor_time = dict["PercentProcessorTime"].ToString(); string working_set = dict["WorkingSet"].ToString(); string working_set_private = dict["WorkingSetPrivate"].ToString(); string pool_nonpaged_bytes = dict["PoolNonpagedBytes"].ToString(); string pool_paged_bytes = dict["PoolPagedBytes"].ToString(); string private_bytes = dict["PrivateBytes"].ToString(); if (!ulong.TryParse(percent_processor_time, out ulong cpu) || !ulong.TryParse(working_set, out ulong set) || !ulong.TryParse(working_set_private, out ulong set_private) || !ulong.TryParse(pool_nonpaged_bytes, out ulong pool_nonpaged) || !ulong.TryParse(pool_paged_bytes, out ulong pool_paged) || !ulong.TryParse(private_bytes, out ulong priv) || string.Compare(name, "_Total", true) == 0 || string.Compare(name, "Idle", true) == 0) { return; } // Sometimes an app will have multiple parts to it. For example, // Chrome will often report chrome, chrome#1, chrome#2, chrome#3, etc. // This is to combine all of those together into a single 'chrome' report. // We sum up the percentages, which I think is OK. Match m = m_process_suffix.Match(name); if (m.Success) { name = m.Groups[1].Value; if (collected_data.TryGetValue(name, out Process p)) { p.Add(cpu, set, set_private, pool_nonpaged, pool_paged, priv); } else { collected_data[name] = new Process(name, cpu, set, set_private, pool_nonpaged, pool_paged, priv); } } else { collected_data[name] = new Process(name, cpu, set, set_private, pool_nonpaged, pool_paged, priv); } } ); // Package the process information into a single Data object that contains a double-dictionary. The dictionary will contain // a mapping from process name to process information, and the process information is itself a dictionary mapping a string // ("Memory", "CPU") to the number representing that. GenericDictionaryData <Process> d = new GenericDictionaryData <Process>(Context); foreach (KeyValuePair <string, Process> process in collected_data) { Process p = process.Value; // The percentage is based on the capacity of a single core, so we have to divide by the # of cores // to get the overall capacity. ulong percent = (ulong)((double)p.CPUNum / (double)m_cores + 0.5f); p.CPUNum = percent; d.Data[p.Name] = p; } return(new CollectedData(Context, d.Data.Count > 0, d)); }