Skip to content

Latest commit

 

History

History
170 lines (110 loc) · 8.58 KB

File metadata and controls

170 lines (110 loc) · 8.58 KB

二、Windows 事件日志

Windows 服务与用户没有交互,因此没有界面。无论需要产生什么输出,通常都会写入某种日志,例如数据库。一个很好的登录位置是窗口事件日志。

Windows 事件日志是计算机警报和通知的记录。微软将事件定义为“系统或程序中需要通知用户或在日志中添加条目的任何重大事件。”

Windows 操作系统按类型对事件进行分类。例如,信息事件描述任务的成功完成,例如安装应用程序。一个警告事件通知管理员潜在的问题,例如磁盘空间不足。错误信息描述了可能导致功能丧失的重大问题。一个成功审核 事件表示一个被审核的安全事件完成,比如一个终端用户成功登录。失败审核事件描述了未成功完成的审核安全事件,例如最终用户通过输入不正确的密码将自己锁在门外。

日志条目中的每个事件都包含以下信息:

  • **日期:**事件发生的日期
  • **时间:**事件发生的时间
  • **用户:**事件发生时登录的用户的名称
  • **计算机:**计算机的名称
  • **事件标识:**指定事件类型的窗口标识号
  • **来源:**引发事件的程序或组件
  • **类型:**事件的类型(信息、警告、错误、安全成功审核或安全失败审核)

视窗事件检视器

窗口事件查看器是一个显示重要事件详细信息的工具(例如,没有按预期启动的程序或自动下载的更新)。在排除 Windows 和其他程序(如 Windows 服务)的问题和错误时,Windows 事件查看器会很有帮助。可以在控制面板的管理工具部分找到窗口事件查看器。

可以通过窗口事件查看器查看窗口事件日志中的条目。这可用于调试服务代码。事实上,这是唯一的方法,因为窗口服务没有用户界面。下图显示了窗口事件查看器的主窗口。

图 4:窗口事件查看器

将服务绑定到窗口事件日志

该服务需要绑定到窗口事件日志,以便在其中写入条目。为此,需要在OnStart方法中放置以下代码。

代码示例 5

          if (!System.Diagnostics.EventLog.SourceExists("MonitorService"))
              System.Diagnostics.EventLog.CreateEventSource("MonitorService", "Application");

如图所示,服务首先查询事件日志,询问先前是否已经创建了MonitorService的事件源。如果没有,则使用CreateEventSource方法创建事件源,该方法指定服务发送的每个日志将被写入Application类型的日志中。

OnStart方法的代码如下:

代码示例 6

          protected override void OnStart(string[] args)
          {
              if (!System.Diagnostics.EventLog.SourceExists("MonitorService"))
                  System.Diagnostics.EventLog.CreateEventSource("MonitorService", "Application");

              this.serviceTimer = new System.Timers.Timer(300);
              this.serviceTimer.AutoReset = true;
              this.serviceTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
              this.serviceTimer.Start();
          }

将事件写入 Windows 事件日志

该服务需要写入 Windows 事件日志,以便与用户通信。为了简化代码,将在类定义代码中编写记录事件的方法。这个方法将接收两个参数:一个包含将要写入日志的消息的字符串,另一个将指示正在保存的事件类型。

事件类型

如前所述,窗口事件日志允许您指定正在保存的事件类型。EventLogEntryType枚举将用于该目的。

允许的类型如下:

  • 信息
  • 警告
  • 错误
  • 安全成功审核(成功审核):当用户成功登录到网络或计算机时,会发生此类事件。
  • 安全失败审核(failure audit):当用户无法登录到网络或计算机时,会发生这种类型的事件。

LogEvent 方法

下面的示例显示了该方法的代码。

代码示例 7

          private void LogEvent(string message, EventLogEntryType entryType)
          {
              System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog();

              eventLog = new System.Diagnostics.EventLog();
              eventLog.Source = "MonitorService";
              eventLog.Log = "Application";
              eventLog.WriteEntry(message, entryType);

          }

如前所示,每次执行该方法时,它都会创建一个EventLog实例。要执行日志条目写入,SourceLog属性需要存储事件源和将在其中写入条目的日志部分。在这种情况下,MonitorService将是条目的来源,Application是日志部分。一旦这些值存储在它们各自的属性中,WriteEntry方法将条目写入窗口事件日志。

到目前为止,类定义代码看起来如何

此时,服务类定义的代码如下所示:

代码示例 8

          public partial class monitorservice : ServiceBase
          {
              private System.Timers.Timer serviceTimer = null;

              public monitorservice()
              {
                  InitializeComponent();
              }

              protected override void OnStart(string[] args)
              {
                  if (!System.Diagnostics.EventLog.SourceExists("MonitorService"))
                      System.Diagnostics.EventLog.CreateEventSource("MonitorService", "Application");

                  this.LogEvent(String.Format("MonitorService starts on {0} {1}", System.DateTime.Now.ToString("dd-MMM-yyyy"), DateTime.Now.ToString("hh:mm:ss tt")), EventLogEntryType.Information);

                  this.serviceTimer = new System.Timers.Timer(300);
                  this.serviceTimer.AutoReset = true;
                  this.serviceTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
                  this.serviceTimer.Start();
              }

              private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
              {

              }

              protected override void OnStop()
              {
                  this.serviceTimer.Stop();
                  this.serviceTimer.Dispose();
                  this.serviceTimer = null;

                  this.LogEvent(String.Format("MonitorService stops on {0} {1}", System.DateTime.Now.ToString("dd-MMM-yyyy"), DateTime.Now.ToString("hh:mm:ss tt")), EventLogEntryType.Information);

              }

              private void LogEvent(string message, EventLogEntryType entryType)
              {
                  System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog();

                  eventLog = new System.Diagnostics.EventLog();
                  eventLog.Source = "MonitorService";
                  eventLog.Log = "Application";
                  eventLog.WriteEntry(message, entryType);

              }

          }

请注意,OnStartOnStop方法会写入 Windows 事件日志,通知它们各自被触发的日期和时间。在这种情况下,它被认为是两者的信息日志条目类型。

| | 提示:每次程序写入 Windows 事件日志时,都应该使用日志条目类型,以便阐明程序写入的原因。 |

章节总结

Windows 事件日志是计算机警报和通知的记录。事件可以定义为“系统或程序中需要通知用户或在日志中添加条目的任何重大事件。”Windows 操作系统按类型对事件进行分类。信息事件描述任务的成功完成;一个警告事件通知管理员潜在的问题;错误信息描述了可能导致功能丧失的重大问题;a 成功审核事件表示已审核安全事件完成,如终端用户成功登录;而失败审核事件描述的是未成功完成的审核安全事件,例如终端用户通过输入不正确的密码将自己锁在门外。

可以通过 Windows 事件查看器查看写入 Windows 事件日志的条目,该查看器位于控制面板的管理工具部分。窗口事件查看器是一个工具,它显示计算机上重大事件的详细信息(例如,未按预期启动的程序或自动下载的更新),在对窗口和其他程序(如窗口服务)的问题和错误进行故障排除时很有帮助。

由于 Windows 服务没有接口,因此在 Windows 事件日志中写入条目是与用户通信的首选方式。为了写入这些条目,服务需要绑定到 Windows 事件日志。这可以使用System.Diagnostics.EventLog命名空间的CreateEventSource()方法来实现。

建议编写一个单独的方法来处理条目编写活动。必须使用EventLogEntryType枚举来阐明为什么每个条目都是由程序编写的。