• windows系统下,C++统计进程内存使用情况


    根据进程名获取进程pid

    #include 
    #include 
    #include 
    #include 
    #include < Windows.h>
    #include 
    #include 
     
     
    DWORD qureyProcessId(std::string name) {
        DWORD pid;
        PROCESSENTRY32 entry;
        entry.dwSize = sizeof(PROCESSENTRY32);
     
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
     
        if (Process32First(snapshot, &entry) == TRUE)
        {
            while (Process32Next(snapshot, &entry) == TRUE)
            {
                if (std::string(entry.szExeFile) == name) {
                    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
                    pid = GetProcessId(hProcess);
                    //std::cout << "pid = " << pid << std::endl;
                    // Do stuff..
                    CloseHandle(hProcess);
                }
            }
        }
        CloseHandle(snapshot);
        return pid;
    }
    int main() {
        auto pid = qureyProcessId("devenv.exe");
        std::cout << "pid of devenv.exe: " << pid << std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    参考:WINDOWS下通过进程名称获取进程PID

    GetProcessMemoryInfo获取进程使用情况

    BOOL GetProcessMemoryInfo(
      [in]  HANDLE                   Process,
      [out] PPROCESS_MEMORY_COUNTERS ppsmemCounters,
      [in]  DWORD                    cb
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • [in] Process 进程的句柄。
    • [out] ppsmemCounters 指向PROCESS_MEMORY_COUNTERS或PROCESS_MEMORY_COUNTERS_EX结构的指针,该结构接收有关进程的内存使用情况的信息。
    • [in] cb ppsmemCounters 结构的大小(以字节为单位)。
    typedef struct _PROCESS_MEMORY_COUNTERS {
      DWORD  cb;
      DWORD  PageFaultCount;
      SIZE_T PeakWorkingSetSize;
      SIZE_T WorkingSetSize;
      SIZE_T QuotaPeakPagedPoolUsage;
      SIZE_T QuotaPagedPoolUsage;
      SIZE_T QuotaPeakNonPagedPoolUsage;
      SIZE_T QuotaNonPagedPoolUsage;
      SIZE_T PagefileUsage;
      SIZE_T PeakPagefileUsage;
    } PROCESS_MEMORY_COUNTERS;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    cb结构大小(以字节为单位)。
    PageFaultCount页错误数。
    PeakWorkingSetSize峰值工作集大小(以字节为单位)。
    WorkingSetSize当前工作集大小(以字节为单位)。
    QuotaPeakPagedPoolUsage峰值分页池使用情况(以字节为单位)。
    QuotaPagedPoolUsage当前页池使用情况(以字节为单位)。
    QuotaPeakNonPagedPoolUsage峰值非分页池使用情况(以字节为单位)。
    QuotaNonPagedPoolUsage当前非分页池使用情况(以字节为单位)。
    PagefileUsage此过程的提交费用值(以字节为单位)。 提交费用是内存管理器为正在运行的进程提交的内存总量。
    PeakPagefileUsage此过程的生存期内提交费用的峰值(以字节为单位)。
    调用demo
    #include 
    #include 
    #include 
    
    // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
    // and compile with -DPSAPI_VERSION=1
    
    void PrintMemoryInfo( DWORD processID )
    {
        HANDLE hProcess;
        PROCESS_MEMORY_COUNTERS pmc;
    
        // Print the process identifier.
    
        printf( "\nProcess ID: %u\n", processID );
    
        // Print information about the memory usage of the process.
    
        hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                        PROCESS_VM_READ,
                                        FALSE, processID );
        if (NULL == hProcess)
            return;
    
        if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
        {
            printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
            printf( "\tPeakWorkingSetSize: 0x%08X\n", 
                      pmc.PeakWorkingSetSize );
            printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
            printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPeakPagedPoolUsage );
            printf( "\tQuotaPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPagedPoolUsage );
            printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPeakNonPagedPoolUsage );
            printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaNonPagedPoolUsage );
            printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
            printf( "\tPeakPagefileUsage: 0x%08X\n", 
                      pmc.PeakPagefileUsage );
        }
    
        CloseHandle( hProcess );
    }
    
    int main( void )
    {
        // Get the list of process identifiers.
    
        DWORD aProcesses[1024], cbNeeded, cProcesses;
        unsigned int i;
    
        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        {
            return 1;
        }
    
        // Calculate how many process identifiers were returned.
    
        cProcesses = cbNeeded / sizeof(DWORD);
    
        // Print the memory usage for each process
    
        for ( i = 0; i < cProcesses; i++ )
        {
            PrintMemoryInfo( aProcesses[i] );
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    MSDN demo
    利用windows API获取当前进程占用内存以及整个系统当前内存使用情况

    demo调用OpenProcess失败,返回错误码,5

    调用OpenProcess失败解决方案
    上面代码,如果非管理员用户,openprocess返回nullptr。
    需要调用下面代码提权:

    void enableDebugPriv()
    {
        HANDLE hToken;
        LUID sedebugnameValue;
        TOKEN_PRIVILEGES tkp;
     
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
            return;
        }
     
        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
        {
            CloseHandle(hToken);
            return;
        }
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Luid = sedebugnameValue;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
        {
            CloseHandle(hToken);
            return;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    调用上面代码后依然失败

    openprocess

    错误代码:5
    Access is denied.访问被拒绝了。

    要打开另一个本地进程的句柄并获得完全访问权限,必须启用SeDebugPrivilege特权。

    您可以通过两种方式更改主令牌或模拟令牌中的权限:

    • 使用AdjustTokenPrivileges函数启用或禁用权限。
    • 使用CreateRestrictedToken函数限制或删除权限。

    AdjustTokenPrivileges无法添加或删除令牌中的权限。它只能启用当前禁用的现有权限或禁用当前启用的现有权限。有关示例,请参见在C++中启用和禁用权限。
    在访问令牌中启用特权允许进程执行以前无法执行的系统级操作。您的应用程序应该彻底验证权限是否适合帐户类型,特别是对于以下强大的权限。

    要为用户帐户分配权限,请参阅为帐户分配权限。

  • 相关阅读:
    DB2中的函数总结归纳
    Layui快速入门之第十节 表单
    igolang学习3,golang 项目中配置gin的web框架
    如何设计出优秀的虚拟展厅,设计虚拟展厅有哪些步骤
    Linux内核有什么之内存管理子系统有什么第五回 —— 小内存分配(3)
    成功解决虚拟机彼此之间免密登录问题:connect to host xxxxxx port 22: Connection timed out
    【React】编程式路由,push 与 replace,withRouter,BrowserRouter 和 HashRouter 的区别
    搭建vue3项目并git管理
    怎么写好论文引言?
    【电力】永磁同步电机-自抗扰控制PMSM ADRC附matlab代码
  • 原文地址:https://blog.csdn.net/haimianjie2012/article/details/127846806