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

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

我想如何使用 [EventLog.WriteEntry](http://msdn.microsoft.com/zh-tw/library/system.diagnostics.eventlog.writeentry\(VS.80\).aspx) 應該不用多說了，但在使用 [EventLog.WriteEntry](http://msdn.microsoft.com/zh-tw/library/system.diagnostics.eventlog.writeentry\(VS.80\).aspx) 之前，卻有幾個蠻重要的觀念要傳達。

如果你要在 EventLog 中建立自己的 LogName 或 EventSource 必須要知道你的程式在執行時「權限」夠不夠的問題。一般來說，我們會用 [EventLog.CreateEventSource](http://msdn.microsoft.com/zh-tw/library/system.diagnostics.eventlog.createeventsource\(VS.80\).aspx) 幫我們建立自訂的 EventSource 與 LogName，但是你若是以 [LocalSystem](http://msdn.microsoft.com/zh-tw/library/system.serviceprocess.serviceaccount.localsystem.aspx) 帳戶執行 Windows Service 的話，並沒有執行這個方法所需的權限，所以解決之道必須在安裝的過程中進行建立，否則在執行 [EventLog.WriteEntry](http://msdn.microsoft.com/zh-tw/library/system.diagnostics.eventlog.writeentry\(VS.80\).aspx) 時會失敗。

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

以下程式範例我是放在 [Installer](http://msdn.microsoft.com/zh-tw/library/system.configuration.install.installer.aspx) 的 [AfterInstall](http://msdn.microsoft.com/zh-tw/library/system.configuration.install.installer.afterinstall.aspx) 事件中：

```csharp
// 由於權限的關係，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 時會發生例外事件。

以下程式範例我是放在 [Installer](http://msdn.microsoft.com/zh-tw/library/system.configuration.install.installer.aspx) 的 [AfterUninstall](http://msdn.microsoft.com/zh-tw/library/system.configuration.install.installer.afteruninstall.aspx) 事件中：

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

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

![EventLog 管理工具](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/434ca7fb97ba653ba698-image_3.png "EventLog 管理工具")

**原始碼**與**執行檔**我都已經放上 [CodePlex](http://www.codeplex.com/)，有需要的人可以去抓來用：EventLog Manager

**相關連結**

-   [EventLog 類別](http://msdn.microsoft.com/zh-tw/library/system.diagnostics.eventlog.aspx)
