C++遍历windows进程及获取进程的各种信息

该代码示例展示了如何在C++中遍历Windows系统进程,获取包括进程名、ID、CPU使用率、内存使用、网络I/O等详细信息。通过`CreateToolhelp32Snapshot`、`OpenProcess`和`QueryFullProcessImageName`等API,实现对进程的全面监控。同时,还提供了获取单个进程CPU使用率、内存和I/O统计的辅助函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++遍历windows进程及获取进程的各种信息

遍历进程

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;
}
C++ 中,遍历所有运行中的进程获取特定类型的句柄,通常涉及操作系统级别的操作,比如使用 Windows API(如 CreateToolhelp32Snapshot 和 Process32First 等函数)或 Linux 下的 `/proc` 文件系统。以下是使用 Windows API 的一个简化示例: ```cpp #include <windows.h> #include <tchar.h> void ListProcessHandles(DWORD processType, HANDLE* handles) { DWORD snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(snapshot, &pe32)) { do { if (pe32.th32ProcessID != GetCurrentProcessId() && !IsBadHandle(pe32.hProcess)) { // 检查进程是否是我们感兴趣的类型 if ((processType == 0 || pe32.th32ProcessID == processType) && pe32.th32Threads > 0) { *handles = OpenProcess(processType, FALSE, pe32.th32ProcessID); // 获取句柄 if (!IsBadHandle(*handles)) { // 打印或处理句柄 _tcprintf(_T("Process %u has handle: %p\n"), pe32.th32ProcessID, *handles); } else { _tcprintf(_T("Failed to open process handle for process %u.\n"), pe32.th32ProcessID); } } } } while (Process32Next(snapshot, &pe32)); CloseHandle(snapshot); } else { _tcprintf(_T("Failed to get the first process entry.\n")); } } // 示例中 processType 可能取值:CREATE_PROCESS, THREAD_BASE_PRIORITY_POSTION,等 int main() { HANDLE handles[100]; // 定义足够大的数组存储句柄 ListProcessHandles(CREATE_PROCESS, handles); return 0; } ``` 在这个示例中,`processType` 参数是一个常量,代表你想要获取的句柄类型,例如 CREATE_PROCESS、THREAD_BASE_PRIORITY_POSTION 等。 请注意,这只是一个基础示例,并非实际项目中的完整代码,它需要适当地错误处理以及权限管理。同时,在 Linux 上,你可以通过 `"/proc/" + pid + "/maps"` 来查看进程内存映射,但这并不是直接获取句柄。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值