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

使用GetFileSizeEx获取Windows系统日志文件大小传入错误句柄问题求助

正确获取EVTX日志文件大小的方法

你遇到的问题核心在于:GetFileSizeEx需要的是文件系统句柄,而你传入的EvtQuery、EvtGetChannelConfigProperty、OpenEventLog返回的都是Windows事件日志子系统的内部句柄,这两类句柄完全不兼容。

为什么之前的句柄不行?

  • EvtQuery和EvtGetChannelConfigProperty返回的是事件日志查询/配置句柄,用于和Windows Event Log服务交互,不是直接指向磁盘上的文件;
  • OpenEventLog返回的是事件日志会话句柄,同样是用于系统事件日志的操作,不是文件系统层面的句柄。

这些句柄只能在对应的Event Log API中使用,无法被GetFileSizeEx这类文件系统API识别,所以才会出现「传入错误句柄」的错误。

正确的实现步骤

要获取%SystemRoot%\System32\winevt\logs下EVTX文件的大小,你需要直接操作磁盘上的文件,步骤如下:

  1. 拼接完整的文件路径(利用GetEnvironmentVariable获取SystemRoot环境变量);
  2. 使用CreateFile打开目标EVTX文件(注意设置正确的共享模式,因为系统可能正在占用该文件);
  3. 调用GetFileSizeEx获取文件大小;
  4. 关闭文件句柄并处理可能的错误。

示例代码

#include <windows.h>
#include <iostream>
#include <string>

int main() {
    // 获取SystemRoot环境变量
    wchar_t systemRoot[MAX_PATH];
    if (!GetEnvironmentVariableW(L"SystemRoot", systemRoot, MAX_PATH)) {
        std::cerr << "获取SystemRoot失败,错误码: " << GetLastError() << std::endl;
        return 1;
    }

    // 拼接目标文件路径,比如Application.evtx
    std::wstring filePath = std::wstring(systemRoot) + L"\\System32\\winevt\\logs\\Application.evtx";

    // 打开文件:需要指定共享模式,因为系统可能正在读写该日志文件
    HANDLE hFile = CreateFileW(
        filePath.c_str(),
        GENERIC_READ,  // 只需要读权限
        FILE_SHARE_READ | FILE_SHARE_WRITE,  // 允许其他进程读写
        nullptr,
        OPEN_EXISTING,  // 打开已存在的文件
        FILE_ATTRIBUTE_NORMAL,
        nullptr
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "打开文件失败,错误码: " << GetLastError() << std::endl;
        return 1;
    }

    // 获取文件大小
    LARGE_INTEGER fileSize;
    if (!GetFileSizeEx(hFile, &fileSize)) {
        std::cerr << "获取文件大小失败,错误码: " << GetLastError() << std::endl;
        CloseHandle(hFile);
        return 1;
    }

    // 输出结果:可以转换为字节、KB、MB等
    std::cout << "文件大小(字节): " << fileSize.QuadPart << std::endl;
    std::cout << "文件大小(MB): " << static_cast<double>(fileSize.QuadPart) / (1024 * 1024) << std::endl;

    // 关闭句柄
    CloseHandle(hFile);
    return 0;
}

额外提示

如果不想硬编码日志文件名,可以先用EvtGetChannelConfigProperty传入EvtChannelConfigLogFilePath参数,获取对应事件通道的实际日志文件路径,再用上述方法打开文件获取大小,这样能更灵活地适配不同的日志通道。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 14:17:47