The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

解說幾個 EventLog 常用操作方法與重要觀念

最近在開發一些 Windows Service 程式,由於過程中修修改改的,所以藉此整理一下思緒,也順手開發出一套簡易的 EventLog 管理工具,可方便建立、刪除、查詢 EventSource 的相關資訊,也可以刪除 LogName 等資料,避免程式在寫入 EventLog 的時候發生錯誤。

我想如何使用 EventLog.WriteEntry 應該不用多說了,但在使用 EventLog.WriteEntry 之前,卻有幾個蠻重要的觀念要傳達。

如果你要在 EventLog 中建立自己的 LogName 或 EventSource 必須要知道你的程式在執行時「權限」夠不夠的問題。一般來說,我們會用 EventLog.CreateEventSource 幫我們建立自訂的 EventSource 與 LogName,但是你若是以 LocalSystem 帳戶執行 Windows Service 的話,並沒有執行這個方法所需的權限,所���解決之道必須在安裝的過程中進行建立,否則在執行 EventLog.WriteEntry 時會失敗。

如果你之前已經建立了 EventSource 且也已經指派了 LogName 的話,如果因為程式修正 LogName 的名稱,且原本機器上的 EventSource 沒有刪除時,也會引發例外事件,解決之道就是先刪除舊的 EventSource 再重建時指派新的 LogName 即可。

以下程式範例我是放在 InstallerAfterInstall 事件中:

// 由於權限的關係,EventSource 必須要在安裝時建立
if (!EventLog.SourceExists(Program.EventSource))
{
	EventLog.CreateEventSource(m_EventSource, m_EventLog);
}

// 如果安裝時發現 EventSource 的 LogName 與我們預期的名稱不同時就重建!
if (EventLog.LogNameFromSourceName(m_EventSource, ".") != m_EventLog)
{
	EventLog.DeleteEventSource(m_EventSource);
	EventLog.CreateEventSource(m_EventSource, m_EventLog);
}

當 Windows Service 要移除時,最好是將安裝時建立的 EventSource 一併移除。移除 EventSource 並不會連帶將 EventLog 中的資料也刪除,只是若有程式也要存取該 EventSource 時會發生例外事件。

以下程式範例我是放在 InstallerAfterUninstall 事件中:

if (EventLog.SourceExists(m_EventSource))
{
    EventLog.DeleteEventSource(m_EventSource);
}

由於我最近都在改別人寫的 Windows Service 程式,也修改了原本的 EventSource 與 LogName 名稱,不過卻發現之前的程式所建立的 EventSource 沒有刪除,導致我改過的程式會一直 hang 住,而且好像也沒有一個方便的工具可以刪除這些沒用的 EventSource,因此我寫了一個小工具幫我做這些事,圖示如下:

EventLog 管理工具

原始碼執行檔我都已經放上 CodePlex,有需要的人可以去抓來用:EventLog Manager

相關連結