using Microsoft.Win32.TaskScheduler.Events;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Microsoft.Win32.TaskScheduler
{
///
/// Dialog that enables editing of event queries, specifically for creating filters.
///
public partial class EventActionFilterEditor : Form
{
private bool internalSet = false;
private int lastLogTimeComboIndex;
private EventQuery ql = new EventQuery();
private bool queryTextIsDirty;
private string subscription;
///
/// Initializes a new instance of the class.
///
public EventActionFilterEditor()
{
InitializeComponent();
// Logged
logTimeCombo.Items.AddRange(LogTimeBaseItems);
logTimeCombo.SelectedIndex = 0;
// Event level
criticalLevelCheckBox.Tag = new int[] { 1 };
errorLevelCheckBox.Tag = new int[] { 2 };
warningLevelCheckBox.Tag = new int[] { 3 };
infoLevelCheckBox.Tag = new int[] { 0, 4 };
verboseLevelCheckBox.Tag = new int[] { 5 };
// Text boxes
eventIDsText.Tag = eventIDsText.Text;
userText.Tag = userText.Text;
computerText.Tag = computerText.Text;
// Logs and providers
eventLogCombo.CheckAllText = EditorProperties.Resources.EventLogsAll;
UpdateLogList(eventLogCombo.Items);
eventSourceCombo.CheckAllText = EditorProperties.Resources.EventSourcesAll;
UpdateProviderList(eventSourceCombo.Items);
eventSourceCombo.Sorted = true;
// Categories
categoryCombo.CheckAllText = EditorProperties.Resources.EventTasksAll;
// Keywords
keywordsCombo.CheckAllText = EditorProperties.Resources.EventKeywordsAll;
keywordsCombo.InitializeFromEnum(typeof(System.Diagnostics.Eventing.Reader.StandardEventKeywords), EditorProperties.Resources.ResourceManager, "EventKeywords", new string[] { "None", "CorrelationHint" });
keywordsCombo.Sorted = true;
ResetFilterControls();
}
///
/// Initializes a new instance of the class.
///
/// The event query XML used to initialize the dialog.
public EventActionFilterEditor(string eventSubscription) : this()
{
this.Subscription = eventSubscription;
}
///
/// Gets or sets the event query XML. Setting this value will reinitialize the dialog.
///
///
/// The event query XML.
///
public string Subscription
{
get { return subscription; }
set
{
if (string.IsNullOrEmpty(value))
{
subscription = null;
ql = new EventQuery();
}
else
{
try
{
ql = EventQuery.Deserialize(value);
subscription = EventQuery.Serialize(ql);
Initialize();
}
catch
{
subscription = value;
}
}
}
}
private void cancelButton_Click(object sender, EventArgs e)
{
Close();
}
private void categoryCombo_SelectedItemsChanged(object sender, EventArgs e)
{
if (!internalSet)
{
ql.Query.Tasks.Clear();
foreach (var item in categoryCombo.SelectedItems)
if (item.Value is int)
ql.Query.Tasks.Add((int)item.Value);
}
}
private void clearButton_Click(object sender, EventArgs e)
{
ResetFilterControls();
}
private void dataBtn_Click(object sender, EventArgs e)
{
using (var dlg = new EventActionFilterDataEditor())
{
dlg.DataItems = new Dictionary(ql.Query.Data);
if (dlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
ql.Query.Data = new Dictionary(dlg.DataItems);
}
}
}
private void editManuallyCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (internalSet)
{
queryText.Enabled = editManuallyCheckBox.Checked;
}
else
{
/*if (editManuallyCheckBox.Checked)
queryText.Enabled = true;
else
{
if (!internalSet)
{
if (MessageBox.Show(this, EditorProperties.Resources.EventTriggerFilterGoManualPrompt, EditorProperties.Resources.EventViewerDialogTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
{
}
}
}*/
}
}
private void EnableControls()
{
bool enableCtrls = eventLogCombo.CheckedItems.Count > 0;
eventLogCombo.Enabled = enableCtrls || byLogRadio.Checked;
eventSourceCombo.Enabled = eventIDsText.Enabled = keywordsCombo.Enabled =
userText.Enabled = computerText.Enabled = enableCtrls;
foreach (TextBox t in new TextBox[] { eventIDsText, userText, computerText })
nullableText_Leave(t, EventArgs.Empty);
}
private void eventIDsText_TextChanged(object sender, EventArgs e)
{
if (!internalSet)
{
bool match = false;
if (eventIDsText.TextLength == 0 || (match = IDRegex.IsMatch(eventIDsText.Text)) || string.Equals(eventIDsText.Text, eventIDsText.Tag))
{
errorProvider.SetError(eventIDsText, String.Empty);
if (match)
ql.Query.IDString = eventIDsText.Text;
}
else
errorProvider.SetError(eventIDsText, EditorProperties.Resources.Error_EventTriggerIDInvalid);
}
}
private void eventLogCombo_SelectedItemsChanged(object sender, EventArgs e)
{
if (!internalSet)
{
ql.Query.Select.Clear();
List selLogs = eventLogCombo.CheckedItems.FindAll(n => !string.IsNullOrEmpty(n.Name)).ConvertAll(n => n.Name);
foreach (string log in selLogs)
ql.Query.AddPath(log);
EnableControls();
}
}
private void eventSourceCombo_SelectedItemsChanged(object sender, EventArgs e)
{
var provs = Array.ConvertAll(eventSourceCombo.SelectedItems, i => (string)i.Value);
if (!internalSet)
{
ql.Query.Providers = new List(provs);
if (eventLogCombo.CheckedItems.Count == 0)
{
var logs = SystemEventEnumerator.GetLogsForProviders(null, provs);
foreach (var log in logs)
eventLogCombo.CheckValue(log);
EnableControls();
}
}
var tasks = SystemEventEnumerator.GetEventTasks(null, provs);
if (tasks.Count == 0)
categoryCombo.Enabled = false;
else
{
categoryCombo.Enabled = true;
categoryCombo.BeginUpdate();
categoryCombo.Items.Clear();
categoryCombo.Items.Add(new DropDownCheckListItem(categoryCombo.CheckAllText));
categoryCombo.Items.AddRange(tasks.ConvertAll(kv => new DropDownCheckListItem(kv.Value, kv.Key)).ToArray());
categoryCombo.EndUpdate();
}
}
private void Initialize()
{
internalSet = true;
try
{
// Log time
InitLogTime(ql.Query.Times);
// Level
var ctrls = new CheckBox[] { criticalLevelCheckBox, errorLevelCheckBox, warningLevelCheckBox, infoLevelCheckBox, verboseLevelCheckBox };
foreach (var cb in ctrls)
for (int i = 0; i < ((int[])cb.Tag).Length; i++)
cb.Checked = ql.Query.Levels.Contains(((int[])cb.Tag)[i]);
// Logs
eventLogCombo.UncheckAllItems();
foreach (var s in ql.Query.Select)
eventLogCombo.CheckValue(s.Path);
// Providers
eventSourceCombo.CheckItems(o => ql.Query.Providers.FindIndex(s => Equals(((DropDownCheckListItem)o).Value, s)) != -1);
byLogRadio.Checked = ql.Query.Providers.Count == 0;
bySourceRadio.Checked = ql.Query.Providers.Count > 0;
// EventIDs
eventIDsText.Text = ql.Query.IDString;
// Tasks
categoryCombo.CheckItems(o => ql.Query.Tasks.FindIndex(i => Equals(((DropDownCheckListItem)o).Value, i)) != -1);
// Keywords
keywordsCombo.CheckedFlagValue = ql.Query.Keywords;
// User
userText.Text = ql.Query.User;
// Computer
computerText.Text = string.Join(",", ql.Query.Computers.ToArray());
}
catch { }
internalSet = false;
EnableControls();
}
private void InitLogTime(EventQuery.CQuery.CTimeCreated time)
{
int selIdx = -1;
if (time == null)
{
selIdx = 0;
}
else if (!time.HasDates)
{
for (int i = 0; i < LogTimeBaseItems.Length; i++)
if (LogTimeBaseItems[i].DiffTime == time.span)
{
selIdx = i;
break;
}
if (selIdx == -1)
throw new ArgumentOutOfRangeException("Unable to identify selection option for specified log time.");
}
else
{
int x = (time.low.HasValue ? 1 : 0) | (time.high.HasValue ? 2 : 0);
string resStr;
switch (x)
{
case 1: resStr = EditorProperties.Resources.EventLogTimeCustomFrom; break;
case 2: resStr = EditorProperties.Resources.EventLogTimeCustomTo; break;
case 3: resStr = EditorProperties.Resources.EventLogTimeCustomFromTo; break;
case 0:
default: resStr = null; break;
}
if (resStr == null)
selIdx = 0;
else
{
string txt = string.Format(resStr, time.low, time.high);
if (logTimeCombo.Items.Count == 7)
logTimeCombo.Items.Insert(6, txt);
else
logTimeCombo.Items[6] = txt;
selIdx = 6;
}
}
logTimeCombo.SelectedIndex = selIdx;
}
private void keywordsCombo_SelectedItemsChanged(object sender, EventArgs e)
{
if (!internalSet)
{
ql.Query.Keywords = keywordsCombo.CheckedFlagValue;
}
}
private void level_checkedChanged(object sender, EventArgs e)
{
if (!internalSet)
{
ql.Query.Levels.Clear();
var ctrls = new CheckBox[] { criticalLevelCheckBox, errorLevelCheckBox, warningLevelCheckBox, infoLevelCheckBox, verboseLevelCheckBox };
foreach (var cb in ctrls)
if (cb.Checked) ql.Query.Levels.AddRange((int[])cb.Tag);
}
}
private void logTimeCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (!internalSet)
{
bool isCustom = logTimeCombo.SelectedIndex == logTimeCombo.Items.Count - 1;
bool isInserted = logTimeCombo.Items.Count == 8 && logTimeCombo.SelectedIndex == 6;
if (isCustom)
{
using (var dlg = new EventActionFilterTimeEditor())
{
if (ql.Query.Times != null && ql.Query.Times.HasDates) { dlg.FromDateTime = ql.Query.Times.low; dlg.ToDateTime = ql.Query.Times.high; }
if (dlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
ql.Query.Times = new EventQuery.CQuery.CTimeCreated(dlg.FromDateTime, dlg.ToDateTime);
InitLogTime(ql.Query.Times);
}
else
logTimeCombo.SelectedIndex = lastLogTimeComboIndex;
}
}
else if (isInserted) { }
else
{
lastLogTimeComboIndex = logTimeCombo.SelectedIndex;
if (logTimeCombo.Items.Count == 8) logTimeCombo.Items.RemoveAt(6);
ql.Query.Times = new EventQuery.CQuery.CTimeCreated(((LogTimeItem)logTimeCombo.Items[lastLogTimeComboIndex]).DiffTime);
}
}
}
private void nullableText_Enter(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
if (string.Equals(tb.Text, tb.Tag))
tb.Clear();
}
}
private void nullableText_Leave(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
if (tb.TextLength == 0)
tb.Text = (string)tb.Tag;
}
}
private void okButton_Click(object sender, EventArgs e)
{
if (this.tabControl.SelectedTab == xmlTab)
{
if (!UpdateQLFromText())
return;
}
this.subscription = EventQuery.Serialize(ql);
this.DialogResult = System.Windows.Forms.DialogResult.OK;
Close();
}
private void queryText_DragDrop(object sender, DragEventArgs e)
{
if (!queryText.Enabled || queryText.ReadOnly)
return;
try
{
string text = string.Empty;
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
text = System.IO.File.ReadAllText(files[0]);
}
else if (e.Data.GetDataPresent(DataFormats.Text, true))
{
text = e.Data.GetData(DataFormats.Text, true).ToString();
}
if (!text.StartsWith("", true, System.Globalization.CultureInfo.CurrentCulture))
throw new FormatException();
queryText.Text = text;
}
catch
{
MessageBox.Show(this, EditorProperties.Resources.Error_InvalidQueryFormat, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void queryText_DragEnter(object sender, DragEventArgs e)
{
if ((queryText.Enabled && !queryText.ReadOnly) && e.Data.GetDataPresent(DataFormats.Text, true) || e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void queryText_TextChanged(object sender, EventArgs e)
{
queryTextIsDirty = true;
}
private void radio_CheckedChanged(object sender, EventArgs e)
{
this.eventLogCombo.Enabled = this.byLogRadio.Checked || this.eventLogCombo.CheckedItems.Count > 0;
this.eventSourceCombo.Enabled = this.bySourceRadio.Checked || this.eventSourceCombo.SelectedItems.Length > 0;
}
private void ResetFilterControls()
{
criticalLevelCheckBox.Checked = warningLevelCheckBox.Checked = verboseLevelCheckBox.Checked =
errorLevelCheckBox.Checked = infoLevelCheckBox.Checked = false;
logTimeCombo.SelectedIndex = 0;
eventIDsText.Text = userText.Text = computerText.Text = string.Empty;
foreach (TextBox t in new TextBox[] { eventIDsText, userText, computerText })
nullableText_Leave(t, EventArgs.Empty);
eventLogCombo.UncheckAllItems();
eventSourceCombo.UncheckAllItems();
categoryCombo.UncheckAllItems();
keywordsCombo.UncheckAllItems();
byLogRadio.Checked = true;
eventLogCombo.Enabled = true;
}
private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPage != xmlTab)
{
e.Cancel = !UpdateQLFromText();
}
}
private bool UpdateQLFromText(bool initForm = true)
{
if (queryTextIsDirty) // && editManuallyCheckBox.Checked)
{
try
{
ql = EventQuery.Deserialize(queryText.Text);
queryTextIsDirty = false;
if (initForm)
Initialize();
}
catch (Exception ex)
{
var s = EditorProperties.Resources.Error_EventFilterBadQuery;
if (ex is InvalidOperationException && ex.InnerException is InvalidOperationException && ex.InnerException.Data.Contains("Remaining text"))
s += string.Format("\r\n" + EditorProperties.Resources.Error_EventFilterBadQueryText, ex.InnerException.Data["Remaining text"].ToString());
MessageBox.Show(this, s, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
return true;
}
private void wrapCheckBox_CheckedChanged(object sender, EventArgs e)
{
queryText.WordWrap = wrapCheckBox.Checked;
}
private void xmlTab_Enter(object sender, EventArgs e)
{
if (!queryTextIsDirty)
{
queryText.Text = EventQuery.Serialize(ql);
queryTextIsDirty = false;
}
}
private void xmlTab_Leave(object sender, EventArgs e)
{
}
private class LogTimeItem
{
public TimeSpan DiffTime;
public string Text;
public override string ToString() { return Text; }
}
private class StringNode
{
public System.Collections.Generic.List Nodes = new System.Collections.Generic.List(0);
public string Path;
public string Text;
public StringNode(string text, string path = null)
{
Text = text;
Path = path;
}
internal StringNode LastChild
{
get { return (Nodes.Count == 0) ? null : Nodes[Nodes.Count - 1]; }
}
public static implicit operator string(StringNode n)
{
return n.Text;
}
public void UpdateTreeView(TreeNodeCollection nodes)
{
nodes.Clear();
UpdateNodes(this.Nodes, nodes);
}
private static void UpdateNodes(System.Collections.Generic.List nodes, TreeNodeCollection coll)
{
foreach (var item in nodes)
{
var n = DropDownCheckTree.AddValue(coll, item.Text, item.Path);
UpdateNodes(item.Nodes, n.Nodes);
}
}
}
#region Static Constuctor and Methods
private static System.Text.RegularExpressions.Regex IDRegex;
private static StringNode Logs;
private static LogTimeItem[] LogTimeBaseItems;
private static List Providers;
static EventActionFilterEditor()
{
IDRegex = new System.Text.RegularExpressions.Regex(@"^-?\d+(-\d+)?(,-?\d+(-\d+)?)*$", System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.CultureInvariant | System.Text.RegularExpressions.RegexOptions.Singleline);
LogTimeBaseItems = new LogTimeItem[7];
LogTimeBaseItems[0] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTimeAnyTime, DiffTime = TimeSpan.Zero };
LogTimeBaseItems[1] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTimeHour, DiffTime = TimeSpan.FromHours(1) };
LogTimeBaseItems[2] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTime12Hours, DiffTime = TimeSpan.FromHours(12) };
LogTimeBaseItems[3] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTimeDay, DiffTime = TimeSpan.FromHours(24) };
LogTimeBaseItems[4] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTimeWeek, DiffTime = TimeSpan.FromDays(7) };
LogTimeBaseItems[5] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTime30Days, DiffTime = TimeSpan.FromDays(30) };
LogTimeBaseItems[6] = new LogTimeItem { Text = EditorProperties.Resources.EventLogTimeCustom };
}
private static void UpdateLogList(TreeNodeCollection nodes, string targetServer = null)
{
if (Logs == null)
{
Logs = new StringNode(null);
// Add standard nodes
StringNode std = new StringNode(EditorProperties.Resources.EventLogParentStandard);
string[] stdLogs = new string[] { "Application", "Security", "Setup", "System", "ForwardedEvents" };
foreach (string s in stdLogs)
std.Nodes.Add(new StringNode(s, s));
std.LastChild.Text = "Forwarded Events";
Logs.Nodes.Add(std);
// Get all event logs and remove standard ones
var list = new List(SystemEventEnumerator.GetEventLogs(targetServer));
list.Sort();
foreach (string s in stdLogs)
list.Remove(s);
// Add app nodes
StringNode lastParent = null, curCompare = null, appNode = new StringNode(EditorProperties.Resources.EventLogParentApps);
Logs.Nodes.Add(appNode);
int max = 0;
var partList = list.ConvertAll(delegate(string s) { var a = s.Split('-', '/', '\\'); max = Math.Max(max, a.Length); return a; });
for (int i = 0; i < partList.Count; i++)
{
lastParent = appNode;
for (int j = 0; j < partList[i].Length; j++)
{
if (curCompare != null && string.Compare(curCompare, partList[i][j], true) == 0)
{
lastParent = curCompare;
curCompare = curCompare.LastChild;
}
else
{
var sn = new StringNode(partList[i][j]);
if (j == partList[i].Length - 1)
sn.Path = list[i];
lastParent.Nodes.Add(sn);
lastParent = sn;
}
}
curCompare = appNode.LastChild;
}
}
Logs.UpdateTreeView(nodes);
}
private static void UpdateProviderList(CheckedListBox.ObjectCollection items, string targetServer = null)
{
if (Providers == null)
{
Providers = new System.Collections.Generic.List(SystemEventEnumerator.GetEventProviders(targetServer, null, true));
}
items.Clear();
items.AddRange(Providers.ConvertAll(s => { var p = s.Split('|'); return new DropDownCheckListItem(p[1], p[0]); }).ToArray());
}
#endregion Static Constuctor and Methods
}
}