ZBLOG

Windows C++ 获取指定进程的网络rx、tx

在Windows中,获取指定进程的网络接收(RX)和发送(TX)数据量并不是直接可用的API,但可以通过几种方法间接实现。常见的方法包括使用 Windows Performance Counters 或利用 WMI(Windows Management Instrumentation)。以下是一些示例:

方法 1: 使用性能计数器

你可以使用 Performance Data Helper (PDH) API 来获取网络统计信息。

#include <windows.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>

void GetNetworkStats(const std::wstring& processName) {
    // Prepare for performance data.
    HQUERY hQuery;
    HCOUNTER hCounterIn, hCounterOut;

    // Create a query to gather performance data.
    PdhOpenQuery(nullptr, 0, &hQuery);

    // Define the counters for bytes received and sent.
    std::wstring counterPathIn = L"\\Process(" + processName + L")\\IO Read Bytes/sec";
    std::wstring counterPathOut = L"\\Process(" + processName + L")\\IO Write Bytes/sec";

    // Add the counters to the query.
    PdhAddCounter(hQuery, counterPathIn.c_str(), 0, &hCounterIn);
    PdhAddCounter(hQuery, counterPathOut.c_str(), 0, &hCounterOut);

    // Collect initial values.
    PdhCollectQueryData(hQuery);

    Sleep(1000); // Wait for a second before collecting again.

    // Collect the new values.
    PdhCollectQueryData(hQuery);

    PDH_FMT_COUNTERVALUE counterValIn;
    PDH_FMT_COUNTERVALUE counterValOut;

    // Get formatted values for RX and TX bytes
    PdhGetFormattedCounterValue(hCounterIn, PDH_FMT_LARGE | PDH_FMT_NOSCALE, nullptr, &counterValIn);
    PdhGetFormattedCounterValue(hCounterOut, PDH_FMT_LARGE | PDH_FMT_NOSCALE, nullptr, &counterValOut);

    std::wcout << L"Bytes Received: " << counterValIn.largeValue << L"\n";
    std::wcout << L"Bytes Sent: " << counterValOut.largeValue << L"\n";

   // Clean up
   PdhCloseQuery(hQuery);
}

int main() {
   std::wstring processName = L"your_process_name"; // replace with your target process name
   GetNetworkStats(processName);
   return 0;
}

方法 2: 使用 WMI

WMI提供了一种更简单的方法来查询系统状态,包括进程的网络使用情况。

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

#pragma comment(lib, "wbemuuid.lib")

void GetProcessNetworkUsage(const wchar_t* processName) {
    
     HRESULT hres;

     // Initialize COM.
     hres = CoInitializeEx(0, COINIT_MULTITHREADED);
     if (FAILED(hres)) {
         std::cerr << "Failed to initialize COM library." << std::endl;
         return;
     }

     hres = CoInitializeSecurity(
         NULL,
         -1,
         NULL,
         NULL,
         RPC_C_AUTHN_LEVEL_DEFAULT,
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL,
         EOAC_NONE,
         NULL);

     IWbemLocator *pLoc = NULL;

     hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator,(LPVOID *)&pLoc);

     IWbemServices *pSvc = NULL;

      hres = pLoc->ConnectServer(
          _bstr_t(L"ROOT\\CIMV2"),
          NULL,
          NULL,
          0,
          NULL,
          0,
          0,
          &pSvc);

      if (FAILED(hres)) {
          std::cerr << "Could not connect. Error code = 0x"
              << std::hex << hres << std::endl;
          pLoc->Release();
           CoUninitialize();
           return;
       }

       // Set security levels on the proxy
       hres = CoInitializeSecurity(
           NULL,
           -1,
           NULL,
           NULL,
           RPC_C_AUTHN_LEVEL_DEFAULT,
           RPC_C_IMP_LEVEL_IMPERSONATE ,
           NULL ,
           EOAC_NONE ,
           NULL );
       
      IEnumWbemClassObject* pEnumerator = NULL;  
      HRESULT hr;

      WCHAR query[256];
      swprintf(query, sizeof(query)/sizeof(WCHAR), 
               L"SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface WHERE Name='%s'", 
               processName); 

      hr= pSvc->ExecWBEM(&query[0], WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY ,NULL,NULL,&pEnumerator );

       IWbemClassObject *pclsObj;   
       ULONG uReturn=0;  
     
       while (pEnumerator) {  
            HRESULT hr= pEnumerator->Next(WBEM_INFINITE ,1,&pclsObj,&uReturn );  

            if (uReturn==0) break;  

            VARIANT vtProp;  

            VariantInit(&vtProp);  
          
            hr= pclsObj->Get(L"InOctets",&vtProp);  
            wprintf(L"InOctets : %d\n", vtProp.ulVal); 
            
            VariantClear(&vtProp); 
           
            hr= pclsObj->Get(L"OutOctets",&vtProp);  
            wprintf(L"OutOctets : %d\n", vtProp.ulVal); 
           
            VariantClear(&vtProp);  

             pclsObj->Release();  
        }  
    
       // Cleanup
       pSvc->Release();
       pLoc->Release();
       CoUninitialize();
}

int main() {
   const wchar_t* processName = L"Ethernet"; // Replace with your network interface name or relevant identifier
   GetProcessNetworkUsage(processName);
   return 0;
}

注意事项:

  • 在调用这些 API 时,你可能需要以管理员权限运行程序。
  • 网络接口名称可能会有所不同,因此确保您为正在监视的特定进程或接口提供正确的名称。
  • 使用 WMI 的方法涉及 COM 和异步操作,所以需要进行额外处理。
  • 上述代码仅作为基本框架,可以根据具体需求进一步修改和完善。

希望这对你有帮助!如果还有其他问题,请告诉我。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=5536

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?