Getting details of an event from Event Log
Im trying to get the details from the event log based on the selection of a item in a listbox. I was trying to put the details into a textbox. I havnt been successful in being able to find a solution on my own. What I have done, and is extremely slow, is reiterating through the event log and finding a match to the index of the log, then displaying the message, but that is a time consuming operation. Is there a much faster way to get directly to the specific log entry based off the index of the log. Im using WPF and C#.
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
EventLog eventLog1 = new EventLog();
eventLog1.Log = "System";
foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries)
{
开发者_开发知识库var newEntry = entry.Index + " - " + entry.EntryType + " - " + entry.TimeWritten + " - " + entry.Source;
backgroundWorker2.ReportProgress(0, newEntry);
}
}
void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var newEntry = (string)e.UserState;
MainWindow.Instance.Dispatcher.BeginInvoke(new Action(delegate() { MainWindow.Instance.listBox1.Items.Add(newEntry); }));
}
And this add each item to the listbox with the index of the item, i then go through and extract the index:
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string p1 = listBox1.SelectedItem.ToString();
string[] id = Regex.Split(p1, @"([\s])");
label1.Content = id[0];
EventLog el = new EventLog();
el.Log = "System";
foreach (System.Diagnostics.EventLogEntry entry in el.Entries)
{
if (entry.Index.ToString() == id[0])
{
label1.Content = entry.Message;
}
}
}
The foreach loop is what causes the hang in the UI, but even if I were to set it on a different thread, as I did while adding the items to the listbox, it would still take some time to go through it all to get the exact index Im looking for. So what Im really looking to do is just to go straight through to that index and grab the message instead of iterating through the whole list searching for it.
Upon looking at your code, here's a quick summary of what I would do:
Remove ProgressChanged
handler. It is intended for reporting current status to user, which you don't do. Instead, call Items.Add
in DoWork
handler.
Create EventLog
once. This just seems nicer and saves you from potentially creating it in a loop if you aren't careful.
Instead of parsing text with regex, create a special class. This is really important and will save you a lot of pain when you need more accurate behavior or don't wish to display index at all. Regular expressions are slow, and data intended for display to user must never be parsed. You must use classes.
Use meaningful names. I know that you didn't clean up the code, but if you want someone to help you over the internet, you really should.
Finally, get item by index. If you looked into the documentation, you would have noticed there's an indexer property that gets item directly by its index.
class EntryItem {
public EntryItem (EventLogEntry entry)
{
EntryIndex = entry.Index;
ItemText = string.Format ("{0} - {1} - {2} - {3}",
entry.Index,
entry.EntryType,
entry.TimeWritten,
entry.Source);
}
public string ItemText { get; private set; }
public int EntryIndex { get; private set; }
public override string ToString ()
{
return ItemText;
}
}
private EventLog log = new EventLog {
Log = "System"
};
private void eventLoader_DoWork (object sender, DoWorkEventArgs e)
{
foreach (EventLogEntry entry in this.log.Entries)
this.Dispatcher.BeginInvoke (() => eventListBox.Items.Add (new EntryItem (entry)));
}
private void eventListBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
{
EntryItem item = eventListBox.SelectedItem as EntryItem;
if (item == null)
return;
var entry = log.Entries [item.EntryIndex];
currentEntryLabel.Content = entry.Message;
}
精彩评论