【问题标题】:Accessing and Querying Event Log in Windows在 Windows 中访问和查询事件日志
【发布时间】:2016-02-15 09:12:56
【问题描述】:

我想知道如何访问事件日志条目。我有一个客户端服务器应用程序,它执行没有问题。我要查找的是 ID 为 1149 的所有日志实例。此日志包含远程连接条目。我截取了一段代码,就在这里。

string logType = "System";
string str = "";
EventLog ev = new EventLog(logType, System.Environment.MachineName);
int LastLogToShow = ev.Entries.Count;
if (LastLogToShow <= 0)
    Console.WriteLine("No Event Logs in the Log :" + logType);

// Read the last 2 records in the specified log. 
int i;
for (i = ev.Entries.Count; i >= LastLogToShow - 1000 ; i--)
{
    EventLogEntry CurrentEntry = ev.Entries[i];
    if (CurrentEntry.InstanceId == 1149)
    {
        str += "Event type: " + CurrentEntry.EntryType.ToString() + "\n" +
               "Event Message: " + CurrentEntry.Message + CurrentEntry + "\n" +
               "Event Time: " + CurrentEntry.TimeGenerated.ToShortTimeString() + "\n" +
               "Event : " + CurrentEntry.UserName +"\n" +"\n";
    }
}
ev.Close();
return str;

问题是我每次都得到 42567 索引超出范围异常。我也不知道在那之后它是否会起作用,所以可能会出现问题。

编辑: 事实上,问题是我像你们说的那样用我的索引从事件日志中伸出援手。使用这条线进行循环解决了我的问题,我现在可以访问事件日志,如果有人环顾四周,这个解决方案对我有用,非常感谢大家。

for (i = ev.Entries.Count - 1; i >= 0; i--)

【问题讨论】:

    标签: c# arrays event-log


    【解决方案1】:

    这个for (i = ev.Entries.Count; i &gt;= LastLogToShow - 1000 ; i--) 导致了您的错误。我真的不明白你在这里想要做什么。如果您的条目少于 1000 个,则您的 i 可能为负数。当您使用负值作为数组的索引时,您将得到“索引超出范围异常”。当您尝试仅处理最后 2 条记录时(正如您在 for 循环上方的评论所建议的那样),您应该使用这个:

    for (i = ev.Entries.Count - 1; i >= ev.Entries.Count - 2; i--)
    

    当然你仍然需要检查是否有超过 2 个条目,因为如果有 0 个条目,代码仍然会进入 for 循环并尝试访问具有负索引的数组:

    if(ev.Entries.Count < 2)
      return str;
    for (i = ev.Entries.Count - 1; i >= ev.Entries.Count - 2; i--)
    

    编辑:另外刚刚注意到,即使有超过 1000 条记录,当您第一次进入 for 循环时,您也会有 ev.Entries[ev.Entries.Count]。由于数组索引是从零开始的,因此您必须从计数中减去 1 才能获得数组的最后一个元素。

    【讨论】:

      【解决方案2】:

      我强烈建议您为此使用 C# Linq。

      添加这个命名空间

      using System.Linq;
      

      Linq 在处理数据方面与 SQL 非常相似。在你的情况下:

      List<string> stringLogs = 
          ev.Entries
              .Where(t => t.InstanceId == 1149)
              .Select(t => GenerateLogString(t))
              .ToList();
      
      public string GenerateLogString(EventLogEntry CurrentEntry)
      {
          return
              string.Format("Event type: {0}\nEvent Message: {1}\nEvent Time: {2}\nEvent: {3}\n",
                  CurrentEntry.EntryType.ToString(),
                  CurrentEntry.Message + CurrentEntry,
                  CurrentEntry.TimeGenerated.ToShortTimeString(),
                  CurrentEntry.UserName)
      }
      

      然后,您可以将字符串日志转换为单个字符串,就像您在那里一样。

      string str = string.Join("/n", stringLogs);
      

      如果您想选择前 2 个日志(如您的评论所建议的那样),请在查询中添加 .Take(2),如下所示。

      List<string> stringLogs = 
          ev.Entries
              .Where(t => t.InstanceId == 1149)
              .Take(2)
              .Select(t => GenerateLogString(t))
              .ToList();
      

      【讨论】:

      • 谢谢,我会使用LINQ,一旦我对程序进行了彻底的测试,它的性能会更好,对吧?
      • 毫无疑问,性能更好,实现更安全。如果您确实使用我的实现,请更新正确答案。 :) 无论您有多少元素,此方法也将起作用。由于您从不使用索引请求元素,因此不可能出现 OutOfRange 异常。
      • 虽然在您的情况下它不是一个大问题,但 LINQ 在处理非常大的数据集时是令人难以置信的,因为您可以使用deferred execution 来防止应用程序上的任何大量负载。如果您需要帮助,请联系我。 :)
      【解决方案3】:

      您只需要将 i 等于 ev.Entries.Count -1。 i = (ev.Entries.Count -1)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-06
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        相关资源
        最近更新 更多