You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#程序中连接Windows特定嵌套事件日志?

问题原因

你用的EventLog类是.NET旧版事件日志API,只能读取传统系统日志(比如Security、Application),根本访问不了Applications & Services分类下的现代Windows事件日志——像Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational这类嵌套日志,必须用System.Diagnostics.Eventing.Reader命名空间下的EventLogQuery、EventLogReader这类新API才能读取。

解决步骤

1. 替换日志读取逻辑

删掉原代码里EventLog eventLog = new EventLog(logChoice, comp);及后续的遍历代码,换成下面的实现:

// 构建查询规则:指定要过滤的事件ID
string query = $"*[System/EventID={eventChoice}]";
EventLogQuery eventLogQuery = new EventLogQuery(
    logChoice, 
    PathType.LogName, 
    query);

// 用EventLogReader读取日志
using (EventLogReader reader = new EventLogReader(eventLogQuery))
{
    EventRecord entry;
    while ((entry = reader.ReadEvent()) != null)
    {
        // 获取事件生成时间
        DateTime time = entry.TimeCreated.Value;
        // 格式化事件消息(新API需要调用FormatDescription获取完整消息)
        string message = entry.FormatDescription();
        
        // 复用你已经写好的IP、账号、域名提取方法
        string ip = GetIP(message);
        string acc = GetAcc(message);
        string domain = GetDomain(message);
        
        // 格式化CSV行,避免时间格式导致的CSV错乱
        string csvOutput = $"{time:yyyy-MM-dd HH:mm:ss},{ip},{acc},{domain}";
        Console.WriteLine(csvOutput);
        csv.AppendLine(csvOutput);
    }
}

2. 日志名称不用改

你用的Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational是完全正确的日志路径,不需要做任何修改。

3. 必须管理员权限

读取这类嵌套日志需要管理员权限,记得右键程序选择“以管理员身份运行”。

4. 补充异常捕获

新增针对日志不存在的异常捕获,方便排查问题:

catch (EventLogNotFoundException ex)
{
    MessageBox.Show($"找不到指定日志:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
完整修改后的CheckEventLog函数

整合后的代码保留了你原有的导出逻辑,替换了核心的日志读取部分:

private void CheckEventLog()
{
    if (exportPath == null || string.IsNullOrEmpty(exportPath.Text))
    {
        MessageBox.Show("请输入导出路径。", "导出错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    // 处理计算机名称(保留你原有的本地逻辑,远程功能可后续恢复)
    comp = System.Environment.MachineName;
    if (!string.IsNullOrEmpty(compInput.Text))
    {
        // 若要恢复远程读取,在这里补全用户名密码逻辑即可
        // comp = compInput.Text;
        // username = usrImp.Text;
        // ... 密码转SecureString的代码
    }

    string filePath = exportPath.Text;
    string csvHeader = "Date/Time,IP Address,Account Name,Account Domain";
    var csv = new StringBuilder();
    csv.AppendLine(csvHeader);

    try
    {
        // 现代事件日志查询逻辑
        string query = $"*[System/EventID={eventChoice}]";
        EventLogQuery eventLogQuery = new EventLogQuery(
            logChoice, 
            PathType.LogName, 
            query);

        using (EventLogReader reader = new EventLogReader(eventLogQuery))
        {
            EventRecord entry;
            while ((entry = reader.ReadEvent()) != null)
            {
                DateTime time = entry.TimeCreated.Value;
                string message = entry.FormatDescription();
                
                string ip = GetIP(message);
                string acc = GetAcc(message);
                string domain = GetDomain(message);

                string csvOutput = $"{time:yyyy-MM-dd HH:mm:ss},{ip},{acc},{domain}";
                csv.AppendLine(csvOutput);
            }
        }

        File.WriteAllText(filePath, csv.ToString());
        csvOUT = csv.ToString();
        MessageBox.Show("导出完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (IOException ex)
    {
        MessageBox.Show($"文件操作错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (InvalidOperationException ex)
    {
        MessageBox.Show($"操作异常:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (EventLogNotFoundException ex)
    {
        MessageBox.Show($"日志不存在:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"未知错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
额外提示
  • 如果要恢复远程读取其他计算机的日志,需要用EventLogSession初始化EventLogReader:
// 远程连接示例
EventLogSession session = new EventLogSession(
    comp,
    username,
    domain,
    securePassword,
    SessionAuthentication.Default);

using (EventLogReader reader = new EventLogReader(eventLogQuery, session))
{
    // 读取逻辑和上面一致
}
  • 事件ID 1149的消息格式和4625不一样,要检查你的正则表达式能不能正确提取对应字段。

内容的提问来源于stack exchange,提问作者TWB503

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:53:25