TOC

遍历进程

bool TraverseProcesses()
{
	std::map<DWORD, ProcessInfo>mapPIdInfo{};
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);

	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE) {
		return false;
	}

	BOOL bResult = Process32First(hProcessSnap, &pe32);
	uint64_t netRecivedBytes = 0, netSentBytes = 0;
	//这个是获取的整个
	//系统的网络io并不是单个进程的。
	//CSystemInfo::GetNetIoBytes(nullptr, netSentBytes, netRecivedBytes, L"");

	while (bResult)
	{
		std::wstring name = pe32.szExeFile;
		auto id = pe32.th32ProcessID;
		
		//PROCESS_QUERY_LIMITED_INFORMATION
		//PROCESS_QUERY_LIMITED_INFORMATION //需要获取所有权限才可获取想要的信息 - PROCESS_ALL_ACCESS
		auto processHaldle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
		if (nullptr == processHaldle)
		{
			bResult = Process32Next(hProcessSnap, &pe32);
			continue;
		}

		DWORD size = MAX_PATH;
		TCHAR sExeName[MAX_PATH] = { 0 };
		if (FALSE == QueryFullProcessImageName(processHaldle, 0, sExeName, &size))
		{
			bResult = Process32Next(hProcessSnap, &pe32);
			continue;
		}
		wstring wstrProcessPath = sExeName;
		//GetModuleFileNameExW(processHaldle,nullptr, szProcessName, MAX_PATH); //win7下出错
		if (nullptr != processHaldle)
		{
			int64_t cpuUsage = 0;
			uint64_t memoryInfo = 0, vmem = 0, readDiskBytes = 0, writeDiskBytes = 0;
			CPorcessInfo::GetCpuUsage(processHaldle, pe32.th32ProcessID, cpuUsage);
			CPorcessInfo::GetMemoryUsage(processHaldle, memoryInfo, vmem);
			CPorcessInfo::GetIoBytes(processHaldle, readDiskBytes, writeDiskBytes);
			
			wstring wstrCmdline;
			auto res = CPorcessInfo::GetProcessCmdLine(processHaldle, wstrCmdline);
			mapPIDInfo.insert({ id, {name, wstrCmdline, id, pe32.cntThreads, cpuUsage, memoryInfo, readDiskBytes, writeDiskBytes, netRecivedBytes, netSentBytes} }); //字典存储
		}
		if (nullptr != processHaldle)
			CloseHandle(processHaldle);
		bResult = Process32Next(hProcessSnap, &pe32);
	}
	CloseHandle(hProcessSnap);
	return true;
}

获取系统进程的相关信息

std::map<int32_t, CpuLastTime> processIdToLastTime;
/// 获取当前进程的cpu使用率,返回false失败  
 bool GetCpuUsage(HANDLE procesHandle, DWORD processId, int64_t& cupUsage);
/// 获取当前进程内存和虚拟内存使用量,返回false失败,true成功  
 bool GetMemoryUsage(HANDLE procesHandle, uint64_t& mem, uint64_t& vmem);
/// 获取当前进程总共读和写的IO字节数,返回false失败,true成功  
bool  GetIoBytes(HANDLE procesHandle, uint64_t& read_bytes, uint64_t& write_bytes);
/// 获取进程的启动参数
bool GetProcessCmdline(HANDLE procesHandle, std::wstring& cmdline);
/// 获取系统每秒网络收发字节数
bool GetNetIoBytes(HANDLE procesHandle, uint64_t& read_bytes, uint64_t& write_bytes, const std::wstring& wszProcessName);
/// 获取指定磁盘的容量信息
bool GetDiskStatus(const wchar_t* path, uint64_t& total, uint64_t& free, uint64_t& usage);
/// 获得CPU的核数  
int32_t GetProcessorNumber();
/// 时间转换  
static uint64_t FileTime2Utc(const FILETIME* ftime)
{
	LARGE_INTEGER li;
	if (ftime == nullptr)return -1;
	li.LowPart = ftime->dwLowDateTime;
	li.HighPart = ftime->dwHighDateTime;
	return li.QuadPart;
}

bool GetCpuUsage(HANDLE processHandle, DWORD processId, int64_t& cpuUsage)
{
	//cpu数量  
	static int32_t processorCount = -1;
	//上一次的时间  
	static int64_t lastTime = 0;
	static int64_t lastSystemTime = 0;

	FILETIME now;
	FILETIME creation_time;
	FILETIME exit_time;
	FILETIME kernel_time;
	FILETIME user_time;
	int64_t system_time = 0;
	int64_t time = 0;
	int64_t system_time_delta = 0;
	int64_t time_delta = 0;

	if (processorCount == -1)
	{
		processorCount = CSystemInfo::GetProcessorNumber();
	}

	GetSystemTimeAsFileTime(&now);
	if (!GetProcessTimes(processHandle, &creation_time, &exit_time,
		&kernel_time, &user_time))
	{
		// We don't assert here because in some cases (such as in the Task Manager)  
		// we may call this function on a process that has just exited but we have  
		// not yet received the notification.  
		return false;
	}
	system_time = (FileTime2Utc(&kernel_time) + FileTime2Utc(&user_time)) / processorCount;
	time = FileTime2Utc(&now);

	if (processIdToLastTime[processId].lastSystemTime == 0 || processIdToLastTime[processId].lastTime == 0)
	{
		processIdToLastTime[processId].lastSystemTime = system_time;
		processIdToLastTime[processId].lastTime = time;
		return false;
	}

	system_time_delta = system_time - processIdToLastTime[processId].lastSystemTime;
	time_delta = time - processIdToLastTime[processId].lastTime;

	if (time_delta <= 0)
	{
		return false;
	}

	// We add time_delta / 2 so the result is rounded.  
	cpuUsage = (system_time_delta * 100 + time_delta / 2) / time_delta;
	processIdToLastTime[processId].lastSystemTime = system_time;
	processIdToLastTime[processId].lastTime = time;
	return true;
}

bool GetMemoryUsage(HANDLE procesHandle, uint64_t& mem, uint64_t& vmem)
{
	PROCESS_MEMORY_COUNTERS pmc;
	if (GetProcessMemoryInfo(procesHandle, &pmc, sizeof(pmc)))
	{
		mem = pmc.WorkingSetSize;
		vmem = pmc.PagefileUsage;
		return true;
	}
	return false;
}

bool GetIoBytes(HANDLE procesHandle, uint64_t& read_bytes, uint64_t& write_bytes)
{
	IO_COUNTERS io_counter;
	if (GetProcessIoCounters(procesHandle, &io_counter))
	{
		read_bytes = io_counter.ReadTransferCount;
		write_bytes = io_counter.WriteTransferCount;
		return true;
	}
	return false;
}

bool GetProcessCmdline(HANDLE procesHandle, std::wstring& cmdline)
{
	PROCESS_BASIC_INFORMATION pbi = {0};
	PEB                       peb;
	//PROCESS_PARAMETERS        ProcParam;
	DWORD                     dwDummy;
	DWORD                     dwSize;
	LPVOID                    lpAddress;
	RTL_USER_PROCESS_PARAMETERS para;
	//获取信息
	if (0 != NtQueryInformationProcess(procesHandle, ProcessBasicInformation, (PVOID)&pbi, sizeof(pbi), NULL))
	{
		return false;
	}
	if (pbi.PebBaseAddress == nullptr)
	{
		//do somthing 
	}
	if (FALSE == ReadProcessMemory(procesHandle, pbi.PebBaseAddress, &peb, sizeof(peb), &dwDummy))
	{
		return false;
	}
	if (FALSE == ReadProcessMemory(procesHandle, peb.ProcessParameters, &para, sizeof(para), &dwDummy))
	{
		return false;
	}

	lpAddress = para.CommandLine.Buffer;
	dwSize = para.CommandLine.Length;

	TCHAR* cmdLineBuffer = new TCHAR[dwSize+1];
	ZeroMemory(cmdLineBuffer, (dwSize + 1) * sizeof(WCHAR));
	if (FALSE == ReadProcessMemory(procesHandle, lpAddress, (LPVOID)cmdLineBuffer, dwSize, &dwDummy))
	{
		delete[] cmdLineBuffer;
		return false;
	}
	cmdline = cmdLineBuffer;

	delete[] cmdLineBuffer;
	return true;
}

int32_t GetProcessorNumber()
{
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	return (int32_t)info.dwNumberOfProcessors;
}

bool GetNetIoBytes(HANDLE procesHandle, uint64_t& sent_bytes, uint64_t& received_bytes, const std::wstring& wszProcessName)
{
	HQUERY  hQuery = nullptr;
	HCOUNTER hcReceived = nullptr, hcSent = nullptr;
	PDH_FMT_COUNTERVALUE cv;

	PDH_STATUS lStatus = PdhOpenQuery(NULL, NULL, &hQuery);

	if (lStatus != ERROR_SUCCESS)return false;
	
	PdhAddCounter(hQuery, L"\\Network Interface(*)\\Bytes Sent/sec", NULL, &hcSent);
	PdhAddCounter(hQuery, L"\\Network Interface(*)\\Bytes Received/sec", NULL, &hcReceived);
	//PdhAddCounter(hQuery, L"\\PhysicalDisk(_Total)\\Avg. Disk Bytes/Write", NULL, &hcWrite);
	//PdhAddCounter(hQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &hcWrite);
	lStatus = PdhCollectQueryData(hQuery);
	if (lStatus != ERROR_SUCCESS)return false;
	Sleep(1000);
	lStatus = PdhCollectQueryData(hQuery);
	if (lStatus != ERROR_SUCCESS)return false;

	lStatus = PdhGetFormattedCounterValue(hcSent, PDH_FMT_LONG, NULL, &cv);
	if (lStatus == ERROR_SUCCESS)sent_bytes = cv.longValue;

	lStatus = PdhGetFormattedCounterValue(hcReceived, PDH_FMT_LONG, NULL, &cv);
	if (lStatus == ERROR_SUCCESS)received_bytes = cv.longValue;

	PdhRemoveCounter(hcSent);
	PdhRemoveCounter(hcReceived);
	PdhCloseQuery(hQuery);
	return true;
}

bool GetDiskStatus(const wchar_t* path, uint64_t& total, uint64_t& free, uint64_t& usage)
{
	ULARGE_INTEGER utotal;
	ULARGE_INTEGER ufree;
	ULARGE_INTEGER uavailable;
	if (FALSE == GetDiskFreeSpaceExW(path, &uavailable, &utotal, &ufree))
	{
		return false;
	}
	free   = ufree.QuadPart;
	total  = utotal.QuadPart;
	usage  = utotal.QuadPart - ufree.QuadPart;
	return true;
}

Q.E.D.