星期二, 5月 24, 2016

[C#] EventLog

根據這篇 逐步解說:探索事件記錄檔、事件來源和項目 改寫的簡易範例,幫助自已了解 EventLog 相關使用
  • WinForm Layout
[C#] EventLog-1
  • Code
using System.Diagnostics;

namespace WalkthroughEventLog
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        EventLog log = new EventLog();
        ErrorProvider errorSource = new ErrorProvider();
        ErrorProvider errorLog = new ErrorProvider();

        private void Form1_Load(object sender, EventArgs e)
        {
            dgvEntry.AutoGenerateColumns = false;
            dtpFormatSetting();

            cboSearchEntryTypeSource();
            cboEventLogEntryTypeSource();
            ControlDefaultValue();

            txtSourceName.Validated += Text_Validated;
            txtLogName.Validated += Text_Validated;

            ExistsCheck();
            EventLogSetting();
            SearchDefault();
        }

        private void Text_Validated(object sender, EventArgs e)
        {
            ExistsCheck();
            EventLogSetting();
        }

        #region EventLog 相關
        /// <summary>
        /// 設定 EventLog.Source 和 EventLog.Log
        /// </summary>
        private void EventLogSetting()
        {
            // Source 是指 Regedit 內的機碼
            log.Source = txtSourceName.Text;
            // 應用程式及服務紀錄檔內會產生一個 Log
            log.Log = txtLogName.Text;
        }

        /// <summary>
        /// 判斷 EventLog 的 Source 是否存在
        /// </summary>
        /// <returns>true 或 false</returns>
        private bool SourceExists()
        {
            return EventLog.SourceExists(txtSourceName.Text); ;
        }

        /// <summary>
        /// 判斷 EventLog 的 Log 是否存在
        /// </summary>
        /// <returns>true 或 false</returns>
        private bool LogExists()
        {
            return EventLog.Exists(txtLogName.Text);
        }

        /// <summary>
        /// EventLog Log 不存在,必須在 lblLogGuide 顯示說明文字
        /// </summary>
        private void LogNotExistsGuide()
        {
            lblLogGuide.Text = $"{txtLogName.Text} 不存在,無法進行讀取";
        }

        /// <summary>
        /// 判斷 EventLog Source 和 Log 是否存在,不存在必須透過 ErrorProvider 提出警告
        /// </summary>
        private void ExistsCheck()
        {
            errorSource.Clear();
            errorLog.Clear();

            if (SourceExists() == false)
                errorSource.SetError(
                    txtSourceName,
                    $"{txtSourceName.Text} 不存在");

            if (LogExists() == false)
                errorLog.SetError(
                    txtLogName,
                    $"{txtLogName.Text} 不存在");
        }
        #endregion

        #region 控件設定相關
        /// <summary>
        /// 設定 DateTimePicker 格式
        /// </summary>
        private void dtpFormatSetting()
        {
            foreach (DateTimePicker dtp in this.Controls.OfType<DateTimePicker>())
            {
                dtp.Format = DateTimePickerFormat.Custom;
                dtp.CustomFormat = "yyyy/MM/dd";
            }
        }

        #region 設定 ComboBox 資料來源
        /// <summary>
        /// 設定 cboEventLogEntryType 資料來源
        /// </summary>
        private void cboEventLogEntryTypeSource()
        {
            ComboBox cbo = FindComboBox("cboEventLogEntryType");
            GetEntryType(cbo);
        }

        /// <summary>
        /// 設定 cboSearchEntryType 資料來源
        /// </summary>
        private void cboSearchEntryTypeSource()
        {
            ComboBox cbo = FindComboBox("cboSearchEntryType");
            cboSearchEntryType.Items.Add("All");
            GetEntryType(cbo);
        }

        private ComboBox FindComboBox(string cboName)
        {
            ComboBox cbo = this.Controls.Find(cboName, false).OfType<ComboBox>().FirstOrDefault();
            if (cbo == null)
                throw new Exception($"{cboName} 控件不存在");

            return cbo;
        }

        private void GetEntryType(ComboBox cbo)
        {
            cbo.Items.Add(EventLogEntryType.Error);
            cbo.Items.Add(EventLogEntryType.FailureAudit);
            cbo.Items.Add(EventLogEntryType.Information);
            cbo.Items.Add(EventLogEntryType.SuccessAudit);
            cbo.Items.Add(EventLogEntryType.Warning);
        }
        #endregion

        /// <summary>
        /// 設定控件初始值
        /// </summary>
        private void ControlDefaultValue()
        {
            txtSourceName.Text = "Source1";
            txtLogName.Text = "NewLog1";
            txtMessage.Text = "EventLog 小範例練習";

            cboEventLogEntryType.SelectedIndex = cboEventLogEntryType.FindStringExact(EventLogEntryType.Information.ToString());

            cboSearchEntryType.SelectedIndex = cboSearchEntryType.FindStringExact("All");

            dtpStartDate.Value = DateTime.Today.AddDays(-7);
            dtpEndDate.Value = DateTime.Today;
        }
        #endregion

        #region 介面操作相關
        private void btnCreateLog_Click(object sender, EventArgs e)
        {
            if (SourceExists())
                EventLog.DeleteEventSource(txtSourceName.Text);

            EventLog.CreateEventSource(txtSourceName.Text, txtLogName.Text);

            ExistsCheck();
            SearchDefault();
        }
        private void btnRemoveSource_Click(object sender, EventArgs e)
        {
            if (SourceExists())
                EventLog.DeleteEventSource(txtSourceName.Text);

            ExistsCheck();
            SearchDefault();
        }
        private void btnDeleteLog_Click(object sender, EventArgs e)
        {
            // 刪除 Log 檔案,會一併連 Source 一起刪除喔
            if (LogExists())
                EventLog.Delete(txtLogName.Text);

            ExistsCheck();
            SearchDefault();
        }
        private void btnWriteEntry_Click(object sender, EventArgs e)
        {
            if (LogExists() == false) return;

            log.WriteEntry(
                txtMessage.Text,
                (EventLogEntryType)cboEventLogEntryType.SelectedItem
                );

            SearchDefault();
        }
        private void btnClearLog_Click(object sender, EventArgs e)
        {
            if (LogExists() == false) return;

            // 清除 Log 裡面的紀錄
            log.Clear();
            SearchDefault();
        }
        #endregion

        #region 讀取 EventLogEntry 相關
        private void ReadEventLogEntry(DateTime StartDate, DateTime EndDate)
        {
            dgvEntry.DataSource = null;

            if (LogExists() == false)
            {
                LogNotExistsGuide();
                return;
            }

            dgvEntry.DataSource = log.Entries.OfType<EventLogEntry>()
                .Where(
                        e =>
                        e.TimeWritten >= StartDate &&
                        e.TimeWritten < EndDate.AddDays(1))
                .ToList();
            EventLogEntryCount();
        }

        private void ReadEventLogEntry(DateTime StartDate, DateTime EndDate, EventLogEntryType EnterType)
        {
            dgvEntry.DataSource = null;
            if (LogExists() == false)
            {
                LogNotExistsGuide();
                return;
            }

            dgvEntry.DataSource = log.Entries.OfType<EventLogEntry>()
                .Where(
                        e =>
                        e.EntryType == EnterType &&
                        e.TimeWritten >= StartDate &&
                        e.TimeWritten < EndDate.AddDays(1))
                .ToList();
            EventLogEntryCount();
        }

        /// <summary>
        /// 計算 EntryCount 資料
        /// </summary>
        private void EventLogEntryCount()
        {
            lblLogGuide.Text = $"{txtLogName.Text} 內,有 {log.Entries.Count} 筆資料";
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            string EntryType = cboSearchEntryType.SelectedItem.ToString();
            if (EntryType == "All")
                SearchDefault();
            else
                ReadEventLogEntry(dtpStartDate.Value, dtpEndDate.Value, (EventLogEntryType)EntryType);
        }

        /// <summary>
        /// 預設搜尋模式
        /// </summary>
        private void SearchDefault()
        {
            ReadEventLogEntry(dtpStartDate.Value, dtpEndDate.Value);
        }
        #endregion
    }
}

  • Source 和 Log 不存在會透過 ErrorProvider 提出警告
[C#] EventLog-2
  • 建立 Source 和 Log 並寫入 Entry 資料
[C#] EventLog-3
  • 事件檢視器內容
[C#] EventLog-4
  • regedit 內路徑:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLogs
[C#] EventLog-5
  • 根據篩選條件,讀取事件檢視器內資料
[C#] EventLog-6

[C#] EventLog-7

沒有留言:

張貼留言