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

如何通过WinAPI获取指定进程的磁盘I/O及网络数据?PDH是否可行?

获取Windows进程磁盘/网络数据的WinAPI实现方案

一、PDH(Performance Data Helper)完全可以实现需求

资源监视器的大部分磁盘、网络性能数据本身就来自Windows性能计数器,而PDH是微软提供的专门操作性能计数器的API,完全能满足你的需求。

关键计数器路径

针对指定进程(可通过进程名或PID定位),常用计数器路径如下:

  • 磁盘读写:
    • 读字节速率:\Process ID(<PID>)\IO Read Bytes/sec
    • 写字节速率:\Process ID(<PID>)\IO Write Bytes/sec
    • 累计读字节:\Process ID(<PID>)\IO Read Bytes
    • 累计写字节:\Process ID(<PID>)\IO Write Bytes
  • 网络收发:
    • 接收字节速率:\Process ID(<PID>)\Bytes Received/sec
    • 发送字节速率:\Process ID(<PID>)\Bytes Sent/sec
    • 累计接收字节:\Process ID(<PID>)\Bytes Received
    • 累计发送字节:\Process ID(<PID>)\Bytes Sent

注:如果用进程名定位,若存在多个同名进程,需用\Process(<进程名>#<序号>)\...格式(比如\Process(notepad#1)\...),但用PID更准确,避免序号变化的问题。

PDH实现步骤(C++示例)

  1. 初始化查询句柄:
PDH_HQUERY query;
PDH_STATUS status = PdhOpenQuery(NULL, 0, &query);
if (status != ERROR_SUCCESS) {
    // 处理错误
}
  1. 添加目标计数器:
PDH_HCOUNTER diskReadCounter;
wchar_t counterPath[256];
swprintf_s(counterPath, L"\\Process ID(%d)\\IO Read Bytes/sec", targetPID);
status = PdhAddCounter(query, counterPath, 0, &diskReadCounter);
if (status != ERROR_SUCCESS) {
    // 处理错误
}
  1. 采集并获取数据:
// 第一次采集(初始值)
PdhCollectQueryData(query);
Sleep(1000); // 间隔1秒
// 第二次采集
PdhCollectQueryData(query);

PDH_FMT_COUNTERVALUE value;
status = PdhGetFormattedCounterValue(diskReadCounter, PDH_FMT_DOUBLE, NULL, &value);
if (status == ERROR_SUCCESS) {
    double readRate = value.doubleValue;
    // 输出或处理速率值
}
  1. 清理资源:
PdhRemoveCounter(diskReadCounter);
PdhCloseQuery(query);

PDH的优缺点

  • 优点:API封装度高,实现简单,直接对应资源监视器的显示数据,无需解析底层事件。
  • 缺点:速率值依赖两次采集的时间差,实时性略差;部分计数器可能因系统版本或权限问题无法访问(需管理员权限读取系统进程数据)。

二、其他WinAPI实现方案

如果需要更细粒度或实时性更高的数据,可使用以下方法:

1. ETW(Event Tracing for Windows)

通过订阅系统级IO和网络事件,直接捕获进程的磁盘操作、网络包数据。例如:

  • 磁盘IO:订阅Microsoft-Windows-FileIO提供者的事件,解析FileIoRead、FileIoWrite事件中的进程ID和字节数。
  • 网络:订阅Microsoft-Windows-TCPIP或Microsoft-Windows-Winsock-AFD提供者的事件,提取进程的TCP/UDP收发数据。

ETW实现复杂度较高,但能获取最原始的操作细节,适合需要深度分析的场景。

2. 原生系统信息查询API

  • 磁盘IO:调用NtQuerySystemInformation并传入SystemProcessIoInformation参数,可获取每个进程的累计磁盘读写字节数(需自行计算速率)。
  • 网络:使用GetExtendedTcpTable和GetExtendedUdpTable获取TCP/UDP连接列表,关联进程ID后统计收发字节数;但该方法仅针对已建立的连接,无法覆盖所有网络操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:25:19