如何在32位程序中测量64位进程的内存使用情况?

时间:2017-01-23 10:36:38

标签: c++ winapi wmi performancecounter

我试图在C ++中测量来自32位进程的64位应用程序的进程内存使用情况(WorkingSetSize)。我尝试使用Toolhelp

void GetProcMemoryInfo(const wchar_t * procName)
{
     PROCESSENTRY32 entry;
     entry.dwSize = sizeof(PROCESSENTRY32);

     HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

     if (Process32First(snapshot, &entry) == TRUE)
     {
         while (Process32Next(snapshot, &entry) == TRUE)
         {
             if (wcscmp(entry.szExeFile, procName) == 0)
             {
                 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
                 PROCESS_MEMORY_COUNTERS objProcessMemoryInfo;

                 if (GetProcessMemoryInfo(hProcess, &objProcessMemoryInfo, sizeof(objProcessMemoryInfo)))
                 {
                      wchar_t szProcessMemoryInfo[100];
                      wsprintf(szProcessMemoryInfo, L"Working Set Bytes (MB): %d\n", objProcessMemoryInfo.WorkingSetSize / (1024 * 1024));
                      OutputDebugString(szProcessMemoryInfo);
                 }
                 CloseHandle(hProcess);
             }
         }
     }
     CloseHandle(snapshot);
}

此解决方案工作正常,但前提是它构建为x64应用程序。否则 - 我得到2^32的最大值。我想的情况是PROCESS_MEMORY_COUNTERS在内部使用SIZE_T。有没有其他方法来衡量进程内存使用情况,对它构建的体系结构不敏感?

1 个答案:

答案 0 :(得分:0)

我找到了答案,可以使用Windows Management Instrumentation

来完成
class WMI 
{
public:
     WMI();
    ~WMI();
     HRESULT Open(LPCTSTR machine=NULL, LPCTSTR user=NULL, LPCTSTR pass=NULL);
     void Close();
     HRESULT GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len);
     int GetLastError();

private:
     IWbemServices *wbem;
     HRESULT result;
     BSTR GetProcQuery(DWORD pid);
};

使用以下函数检索属性值:

HRESULT WMI::GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len)
{
    IWbemClassObject *obj;
    VARIANT var;

    result = wbem->GetObject(GetProcQuery(pid), 0, 0, &obj, 0);

    if (FAILED(result)) {
        return result;
    }

    result = obj->Get(name, 0, &var, 0, 0);

    if (SUCCEEDED(result)) {
        if (var.vt == VT_NULL) {
            result = E_INVALIDARG;
        }
        else {
            lstrcpyn(value, var.bstrVal, len);
        }
        VariantClear(&var);
    }

    obj->Release();

    return result;
}

使用以下函数检索内存使用量值:

int wmiGetMemProc(uint64_t pid, uint64_t *procmem)
{
    int status;
    TCHAR buf[MEM_MAX];
    WMI *wmi = new WMI();

    if (FAILED(wmi->Open())) {
        return wmi->GetLastError();
    }

    if (FAILED(wmi->GetProcStringProperty(pid, L"WorkingSetSize", buf, MEM_MAX))) {
        status = wmi->GetLastError();
    }
    else {
        *procmem = _wcstoui64(buf, NULL, 10);
    }

    wmi->Close();
    delete wmi;

    return status;
}

它运作得很好。