专栏首页24K纯开源OpenProcess打开进程返回错误的问题

OpenProcess打开进程返回错误的问题

问题描述

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

      需要的信息和上图相差无几。说起来也不算太难,毕竟现成的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);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Mac OS X平台下QuickLook开发教程

    一、引言       Quick Look技术是Apple在Mac OS X 10.5中引入的一种用于快速查看文件内容的技术。用户只需要选中文件单击空格键即可快...

    24K纯开源
  • macOS平台下Qt应用程序菜单翻译及调整

    在macOS平台上,系统会为应用程序菜单添加一些额外的菜单项。先来看一些典型的例子:

    24K纯开源
  • RegQueryValueEx正确使用方法

          项目中需要读取注册表中的HKEY_CLASSES_ROOT主键下一个子键的值,看了看MSDN的说明,有RegOpenKeyEx和RegQueryVa...

    24K纯开源
  • System方法总结

    最近在研究Android源码,突然看到有很多和System有关,什么System.arraycopy、System.nanoTime(),所以专门花时间看了一下...

    haifeiWu
  • 数据分析报告,就该这么写

    很多同学喜欢问:有没有数据分析报告模板可以抄。其实如果掌握了写报告的方法,根本不需要模板抄。而所谓的模板,为了图高大全,往往章节很多很多很多。真实工作中真这么汇...

    接地气的陈老师
  • 一个数据分析师必须训练的思维方式

    分享一个人人都知道,但人人都难做到的思维方式:“具体问题、具体分析”。是滴,估计大家从小学的思想政治课本就听过这八个字。问题是:这句话本身很不具体啊!到底啥样子...

    接地气的陈老师
  • 还在用Android正经布局来写页面吗?

    ConstraintLayout布局出来已经很久了,刚出来那会儿就想尝试一下的,结果半天都没适应,前两天看到一篇ConstraintLayout实战的文章,看完...

    用户2802329
  • 教程 | 重新发现语义分割,一文简述全卷积网络

    语义分割是一种学习如何识别图像中对象范围的机器学习技术。语义分割赋予机器学习系统与人类相似的理解图像内容的能力。它促使机器学习算法定位对象的精准边界,无论是街景...

    机器之心
  • 从0到1,马蜂窝大交通团队如何构建高效研发流程体系?

    2019年5月,马蜂窝完成了新一轮融资,金额达2.5亿美元。这也标志着通过集内容、社区、交易为一体的消费决策场景构建,从攻略社区起家的马蜂窝开始迈入在线旅游行业...

    TAPD敏捷研发
  • Python中如何把redis取出的数据去掉b'

    这个问题是最近在写爬虫的时候遇到的,本次使用了redis对爬取的数据进行存储,便于对数据进行二次清洗。存入的过程是非常顺利的。但是在二次数据清洗时,在redis...

    申霖

扫码关注云+社区

领取腾讯云代金券