问题描述

项目中需要做一个小功能:能够查看系统中当前正在运行的进程的内存信息,如内存块类型、分配状态、访问权限等。如下图所示:

需要的信息和上图相差无几。说起来也不算太难,毕竟现成的API已经提供了。我们要做的就是遍历获取每个进程的句柄,然后逐个打开就可以提取信息了。

排查结论

但是,当我逐步编写完代码并运行时,发现什么结果也没得到。于是乎,打开调试器下了几个断点跟了进去发现:GetLastError()的返回值在遇到System Process时,会返回错误代码87。回头一查MSDN,人家已然说明:当OpenProcess()给定的进程ID为0时,该函数会失败并且GetLastError()返回的错误代码是ERROR_INVALID_PARAMETER。这个错误代码值就是87。另外还说明了,当给定的进程是空闲进程(Idle Process)或CSRSS进程之一时,GetLastError()返回的错误代码是ERROR_ACCESS_DENIED,其值为5. 出于系统安全性考虑,操作系统禁止用户层代码打开这些进程。

显然,错误很明显了。我并没有过滤这些特殊进程,而是一股脑的全部调用OpenProcess()打开进程。而刚好,我的系统上第一个遍历的进程就是System Process(进程ID为0)。于是程序直接跳出了而得不到任何结果。另外,我的系统是Windows 7 64位系统,网上有人说在Windows XP系统上不会出现这种错误,不知道真假。

遍历进程并打开:

HANDLE proc = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (proc == INVALID_HANDLE_VALUE)
{
assert(proc != INVALID_HANDLE_VALUE);
return ;
}
ProcessMemory item;
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
PROCESSENTRY32 procEntry = { 0 };
procEntry.dwSize = sizeof(PROCESSENTRY32);
BOOL bRet = Process32First(proc,&procEntry);
while (bRet)
{
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION| PROCESS_VM_READ, FALSE, procEntry.th32ProcessID );
if (NULL == hProcess)
{
int ret = GetLastError();
// skip the system process and Idle process or one of CSRSS process
if (ret != ERROR_INVALID_PARAMETER && ret != ERROR_ACCESS_DENIED)
return; // function failed for other errors
}
else
{
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
item.pname = procEntry.szExeFile;
item.pid = procEntry.th32ProcessID;
item.PageFaultCount = pmc.PageFaultCount;
item.PagefileUsage = pmc.PagefileUsage;
item.PeakPagefileUsage = pmc.PeakPagefileUsage;
item.PeakWorkingSetSize = pmc.PeakWorkingSetSize;
item.QuotaNonPagedPoolUsage = pmc.QuotaNonPagedPoolUsage;
item.QuotaPagedPoolUsage = pmc.QuotaPagedPoolUsage;
item.QuotaPeakNonPagedPoolUsage = pmc.QuotaPeakNonPagedPoolUsage;
item.QuotaPeakPagedPoolUsage = pmc.QuotaPeakPagedPoolUsage; m_procsmem.push_back(item);
}
} bRet = Process32Next(proc, &procEntry);
}
CloseHandle(hProcess);
CloseHandle(proc);

  

OpenProcess打开进程返回错误的问题的更多相关文章

  1. Win32 OpenProcess打开进程失败,返回5无权限操作

    Win32 OpenProcess打开进程失败,返回5无权限操作,相信你会碰到这样的事,在IDE中可以,单独却不可以了,其实这时就需要提权了,否则是无法打开的,OpenProcess提权至Debug即 ...

  2. 查看进程所用的内存(使用GetWindowThreadProcessId取得进程ID,OpenProcess打开进程和GetProcessMemoryInfo取得内存信息)

    // function GetProcessMemorySize(_sProcessName: string; var _nMemSize: Cardinal): Boolean; var l_nWn ...

  3. C#操作FTP报错,远程服务器返回错误:(550)文件不可用(例如,未找到文件,无法访问文件)的解决方法

    最近在做项目的时候需要操作ftp进行文件的上传下载,但在调用using (var response = (FtpWebResponse)FtpWebRequest.GetResponse())的时候总 ...

  4. 写自动更新程序出现"远程服务器返回错误: (404) 未找到"

    在win2003配置后,在客户端运行时能够下载exe和dll文件,但是在更新lib文件时总是报“远程服务器返回错误: (404) 未找到”错误,不明白咋会出现这个问题,去网上一查,发现以下解决办法: ...

  5. HttpWebResponse远程服务器返回错误: (500) 内部服务器错误。

    现象 我们编码实现请求一个页面时,请求的代码类似如下代码: HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strUrl); req.Us ...

  6. IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法IIS上部署MVC网站,打开后500错误

    IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法 IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrl ...

  7. NuGet在Push的时候提示“远程服务器返回错误:(403)已禁用”问题解决

    在使用NuGet把包push到nuget官网的时候,提示了如下信息: Failed to process request. 'The specified API key is invalid or d ...

  8. C# FTP远程服务器返回错误:(550) 文件不可用(例如,未找到文件,无法访问文件)

    今天用代码删除FTP服务器上的目录时候,报错:远程服务器返回错误:(550) 文件不可用(例如,未找到文件,无法访问文件). 习惯性的google,不外乎以下几点: 1.URL路径不对,看看有没有多加 ...

  9. ajax提交后完全不进入action直接返回错误

    今天遇到个问题就是jQuery提交ajax请求,居然没有进入action的断点而直接返回错误信息. 仔细排查后才发现原来是因为客户端提交的某字段是100w的值,而后台对应的字段是个Short类型,根本 ...

随机推荐

  1. VS2010在运行状态下编辑代码

    在VS2010环境下,当程序处于调试运行状态时,编辑代码会出现下图提示框: 这就给边编辑代码边查看程序运行效果带来不便. 解决方法:在程序没有运行的时候,打开菜单“工具”——>“选项”——> ...

  2. 第一部分:IBM量子体验

    (一)量子世界    今天的计算机使用标准的(或用物理学家的话来说,“经典的”)计算模型来执行计算与处理信息,此计算模型要追溯到图灵(Turing)和冯・诺伊曼(Von Neumann)时期.在此模型 ...

  3. sctp和tcp的区别

    作为一个传输层协议,SCTP兼有TCP及UDP两者的特点.SCTP可以称为是TCP的改进协议,但他们之间仍然存在着较大的差别.首先SCTP和TCP之间的最大区别是SCTP的连接可以是多宿主连接的,TC ...

  4. INSTALL MYSQL IN MAC

    安装好MYSQL后,在System References中找到MYSQL,启动它. 启动之后在终端中输入添加MySQL路径的命令,把MYSQL路径添加到PATH中: PATH="$PATH& ...

  5. EntityFramework Code First 添加唯一键

    在EntityFramework 6.1后可以直接使用 [Index("TitleIndex", IsUnique = true)] public string Title { g ...

  6. 迁移SQL SERVER 数据库实例

    由于某些原因,需要将2个数据库实例合并为1个,也就是说要把其中的一台迁移到另外一台上面. 背景介绍 :下面的B,C代表2个实例,要把B中相关东西迁移到C实例上面.其中B上面有一部分的同步是从另外一台服 ...

  7. 用Jquery load text文本到網頁遇到的問題

    HTML <div id="divText"></div> Javascript $('#divText').load(fileName ,function ...

  8. 通过微信查找SAP TCODE代码

    输入T-CODE查询作用: (包含了16000+ 个SAP T-CODE),扫码关注后可以体验效果 再也不用去记那么多T-CODE用途了 还不试试看 输入关键词:"利润中心" &q ...

  9. 领域驱动开发推荐代码示例 — Microsoft NLayerApp

    简介: Microsoft NLayerApp是由微软西班牙团队出品的基于.NET 4.0的“面向领域N层分布式架构”代码示例,在codeplex上的地址是:http://microsoftnlaye ...

  10. git delete repository