VC获取进程的cpu使用率、内存、线程数、句柄数等信息

//ProcessInfoCollect.h

//进程信息采集

#pragma once


//枚举进程
typedef BOOL(_stdcall *ENUMPROCESS)(
	DWORD *pProcessIds,    //指向进程ID数组链
	DWORD cb,              //ID数组的大小,用字节计数
	DWORD *pBytesReturned  //返回的字节
	);

//枚举进程模块
typedef BOOL(_stdcall *ENUMPROCESSMODULES)(
	HANDLE  hProcess,   //进程句柄
	HMODULE *lphModule, //指向模块句柄数组链
	DWORD   cb,         //模块句柄数组大小,字节计数
	LPDWORD lpcbNeeded  //存储所有模块句柄所需的字节数
	);

//获得进程模块名
typedef DWORD(_stdcall *GETMODULEFILENAMEEX)(
	HANDLE  hProcess,   //进程句柄
	HMODULE hModule,    //进程句柄
	LPTSTR  lpFilename, //存放模块全路径名
	DWORD   nSize       //lpFilename缓冲区大小,字符计算
	);

//获得进程名
typedef DWORD(_stdcall *GETMODULEBASENAME)(
	HANDLE  hProcess,  //进程句柄
	HMODULE hModule,   //模块句柄
	LPTSTR  lpBaseName,//存放进程名
	DWORD   nSize      //lpBaseName缓冲区大小
	);

//进程信息结构
typedef struct tagProcessInfo 
{
	DWORD dwPID;//进程ID
	char  szFileName[MAX_PATH];//进程文件名
	char  szPathName[MAX_PATH];//进程路径名
}ProcessInfo;

class ProcessInfoCollect
{
public:
	ProcessInfoCollect();
	virtual ~ProcessInfoCollect();

	//提权
	BOOL	EnablePrivilege(HANDLE hToken, LPCSTR szPrivName);

	//枚举所有进程
	BOOL	EnumAllProcess(ProcessInfo *pAll, int & nTotal);
	//启动进程
	BOOL	CreateNewProcess(LPCSTR pszExeName, WORD wShowWindow, HANDLE &hToken, DWORD & dwProcessID);
	//关闭进程
	int		KillProcess(DWORD nProcessID);

	//获取指定进程的所有子进程
	BOOL	GetChildProcessID(DWORD dwParentPID, DWORD* pChildProcess, int & nChildProcessNum);
	//获取进程所属令牌
	HANDLE	GetProcessToken(DWORD dwPID);
	//根据程序名获取进程ID
	DWORD	GetProcessIDByName(const char* pAppFileName);	   

	//获取当前进程的cpu使用率
	BOOL    GetCPUUserRate(double & dCPUUserRate);
	//获取指定进程的cpu使用率
	BOOL    GetCPUUserRate(DWORD lProcessID, double & dCPUUserRate);

	//获取当前进程的IO计数
	int		GetIOBytes(ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct);
	//获取指定进程的IO计数
	int		GetIOBytes(DWORD lProcessID, ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct);

	//获取当前进程的内存
	BOOL	GetMemoryUsed(DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize);
	//获取指定进程的内存
	BOOL	GetMemoryUsed(DWORD lProcessID, DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize);

	//获取句柄数
	BOOL	GetHandleCount(DWORD &dwHandles);
	BOOL	GetHandleCount(DWORD lProcessID, DWORD &dwHandles);

	//获取线程数
	BOOL	GetThreadCount(DWORD &dwThreads);
	BOOL	GetThreadCount(DWORD lProcessID, DWORD &dwThreads);

#ifdef StartProcessBySysServiceEx_Flag
	//启动进程(通过服务启用进程)
	BOOL	StartProcessBySysServiceEx(const char* pAppFullFileName, const char* pRunParameter);
#endif

protected:
	//获取指定进程的cpu使用率
	BOOL    GetCPUUserRateEx(HANDLE hProccess, double & dCPUUserRate);

	//获取指定进程的IO计数
	int		GetIOBytesEx(HANDLE hProccess, ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct);

	//获取内存
	//参数:hProccess:进程句柄;dwPeakWorkingSetSize:使用内存高峰;dwWorkingSetSize:当前使用的内存;
	BOOL	GetMemoryUsedEx(HANDLE hProccess, DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize);

	//获取句柄数
	BOOL	GetHandleCountEx(HANDLE hProccess, DWORD &dwHandles);

	//中断进程
	BOOL	TerminateProcessEx(DWORD   dwPID, DWORD  dwTimeout);
	//启动进程
	BOOL	StartProcess(LPCSTR pAppFullFileName, DWORD &dwProcessID, WORD wShowWindow);

	//启动进程(通过服务启用进程)
	HANDLE	StartProcessBySysService(const char* pAppFullFileName, const char* pRunParameter, HANDLE hToken);
};

//ProcessInfoCollect.cpp

#include "stdafx.h"
#include "ProcessInfoCollect.h"
#include <stdio.h>
#include <tchar.h>
#include <TLHELP32.H>
#include <winsvc.h>
#include <psapi.h>
#pragma comment(lib,"psapi.lib")

#ifdef StartProcessBySysServiceEx_Flag
#include <Userenv.h>
#include <WtsApi32.h>
#include <atlbase.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma comment(lib,"Userenv.lib")
#endif


#define			MAX_ID							4096			//最大进程数
#define			MAX_CHILD_PROCESS_COUNT			256				//子进程数

//得到文件名(包含扩展名)  
const char* GetFileName(const char* pFile)
{
	if (NULL == pFile || 0 == strlen(pFile))
	{
		return "";
	}

	const char *pPos = strrchr(pFile, '\\');
	if (NULL == pPos)
	{
		pPos = strrchr(pFile, '/');

		if (NULL == pPos)
		{
			return "";
		}
	}

	return pPos + 1;
}

//得到文件名(不含扩展名)  
void GetFileNameWithoutExtendName(const char* pFile, char *pFileDest)
{
	if (NULL == pFile || 0 == strlen(pFile) || NULL == pFileDest)
		return;

	char *pPos = (char *)strrchr(pFile, '\\');
	if (NULL == pPos)
	{
		pPos = (char *)strrchr(pFile, '/');
	}
	if (NULL == pPos)
	{
		pPos = (char *)pFile;
	}
	if (pPos != NULL)
	{
		char *pSplitFlag = strrchr(pPos, '.');
		if (pSplitFlag != NULL)
		{
			int nLenTemp = pSplitFlag - pPos - 1;
			strncpy(pFileDest, pPos + 1, nLenTemp);
			pFileDest[nLenTemp] = '\0';
		}
		else
		{
			strcpy(pFileDest, pPos + 1);
		}
	}
	else
	{
		strcpy(pFileDest, pFile);
	}
}

#define TokenLinkedToken 19

#ifdef StartProcessBySysServiceEx_Flag
DWORD GetActiveSessionID()
{
	DWORD dwSessionId = 0;
	PWTS_SESSION_INFO pSessionInfo = NULL;
	DWORD dwCount = 0;
	WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
	for (DWORD i = 0; i < dwCount; i++)
	{
		WTS_SESSION_INFO si = pSessionInfo[i];
		if (WTSActive == si.State)
		{
			dwSessionId = si.SessionId;
			break;
		}
	}
	WTSFreeMemory(pSessionInfo);
	return dwSessionId;
}
#endif

ProcessInfoCollect::ProcessInfoCollect()
{
}

ProcessInfoCollect::~ProcessInfoCollect()
{
}

//获取cpu使用率
BOOL  ProcessInfoCollect::GetCPUUserRate(double & dCPUUserRate)
{
	HANDLE hProcess = ::GetCurrentProcess();
	return GetCPUUserRateEx(hProcess, dCPUUserRate);
}

//获取指定进程的cpu使用率
BOOL    ProcessInfoCollect::GetCPUUserRate(DWORD lProcessID, double & dCPUUserRate)
{
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lProcessID);
	if (hProcess == NULL)
		return FALSE;

	BOOL bSuccess = GetCPUUserRateEx(hProcess, dCPUUserRate);
	CloseHandle(hProcess);
	return bSuccess;
}

int ProcessInfoCollect::GetIOBytes(ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct)
{
	HANDLE hProcess = GetCurrentProcess();//获取当前进程句柄
	int nRet = GetIOBytesEx(hProcess, read_bytes, write_bytes, wct, rct);
	return nRet;
}
//获取指定进程的IO计数
int	ProcessInfoCollect::GetIOBytes(DWORD lProcessID, ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct)
{
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lProcessID);
	if (hProcess == NULL)
		return -1;

	int nRet = GetIOBytesEx(hProcess, read_bytes, write_bytes, wct, rct);
	CloseHandle(hProcess);
	return nRet;
}

//获取句柄数
BOOL	ProcessInfoCollect::GetHandleCount(DWORD &dwHandles)
{
	return GetHandleCountEx(GetCurrentProcess(),dwHandles);
}
BOOL	ProcessInfoCollect::GetHandleCount(DWORD lProcessID, DWORD &dwHandles)
{
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lProcessID);
	if (hProcess == NULL)
		return FALSE;

	BOOL bSuccess = GetHandleCountEx(hProcess, dwHandles);
	CloseHandle(hProcess);
	return bSuccess;
}

//获取当前进程的内存
BOOL	ProcessInfoCollect::GetMemoryUsed(DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize)
{
	HANDLE hProcess = GetCurrentProcess();//获取当前进程句柄
	return GetMemoryUsedEx(hProcess, dwPeakWorkingSetSize, dwWorkingSetSize);
}
//获取指定进程的内存
BOOL	ProcessInfoCollect::GetMemoryUsed(DWORD lProcessID, DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize)
{
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lProcessID);
	if (hProcess == NULL)
		return FALSE;

	BOOL bSuccess = GetMemoryUsedEx(hProcess, dwPeakWorkingSetSize, dwWorkingSetSize);
	CloseHandle(hProcess);
	return bSuccess;
}

//获取指定进程的cpu使用率
BOOL    ProcessInfoCollect::GetCPUUserRateEx(HANDLE hProccess, double & dCPUUserRate)
{
	static DWORD s_dwTickCountOld = 0;
	static LARGE_INTEGER s_lgProcessTimeOld = { 0 };
	static DWORD s_dwProcessorCoreNum = 0;
	if (!s_dwProcessorCoreNum)
	{
		SYSTEM_INFO sysInfo = { 0 };
		GetSystemInfo(&sysInfo);
		s_dwProcessorCoreNum = sysInfo.dwNumberOfProcessors;
	}
	double dbProcCpuPercent = 0;
	BOOL bRetCode = FALSE;
	FILETIME CreateTime, ExitTime, KernelTime, UserTime;
	LARGE_INTEGER lgKernelTime;
	LARGE_INTEGER lgUserTime;
	LARGE_INTEGER lgCurTime;
	bRetCode = GetProcessTimes(hProccess, &CreateTime, &ExitTime, &KernelTime, &UserTime);
	if (bRetCode)
	{
		lgKernelTime.HighPart = KernelTime.dwHighDateTime;
		lgKernelTime.LowPart = KernelTime.dwLowDateTime;
		lgUserTime.HighPart = UserTime.dwHighDateTime;
		lgUserTime.LowPart = UserTime.dwLowDateTime;
		lgCurTime.QuadPart = (lgKernelTime.QuadPart + lgUserTime.QuadPart);
		if (s_lgProcessTimeOld.QuadPart)
		{
			DWORD dwElepsedTime = ::GetTickCount() - s_dwTickCountOld;
			dbProcCpuPercent = (double)(((double)((lgCurTime.QuadPart - s_lgProcessTimeOld.QuadPart) * 100)) / dwElepsedTime) / 10000;
			dbProcCpuPercent = dbProcCpuPercent / s_dwProcessorCoreNum;
		}
		s_lgProcessTimeOld = lgCurTime;
		s_dwTickCountOld = ::GetTickCount();
	}
	dCPUUserRate = dbProcCpuPercent;
	return bRetCode;
}
//获取指定进程的IO计数
int		ProcessInfoCollect::GetIOBytesEx(HANDLE hProccess, ULONGLONG * read_bytes, ULONGLONG * write_bytes, ULONGLONG * wct, ULONGLONG * rct)
{
	IO_COUNTERS io_counter;
	if (GetProcessIoCounters(hProccess, &io_counter))
	{
		if (read_bytes) *read_bytes = io_counter.ReadTransferCount;//字节数
		if (write_bytes) *write_bytes = io_counter.WriteTransferCount;
		if (wct) *wct = io_counter.WriteOperationCount;//次数
		if (rct) *rct = io_counter.ReadOperationCount;
		return 0;
	}
	return -1;
}

//获取内存
//参数:hProccess:进程句柄;dwPeakWorkingSetSize:使用内存高峰;dwWorkingSetSize:当前使用的内存;
BOOL	ProcessInfoCollect::GetMemoryUsedEx(HANDLE hProccess, DWORD & dwPeakWorkingSetSize, DWORD & dwWorkingSetSize)
{
	//根据进程ID打开进程
	if (hProccess)
	{
		SYSTEM_INFO si;
		GetSystemInfo(&si);
		OSVERSIONINFO osvi;//定义OSVERSIONINFO数据结构对象
		memset(&osvi, 0, sizeof(OSVERSIONINFO));//开空间 
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);//定义大小 
		GetVersionEx(&osvi);//获得版本信息 
		if (osvi.dwMajorVersion < 6)
		{
			PROCESS_MEMORY_COUNTERS pmc;
			pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
			//获取这个进程的内存使用情况。
			if (::GetProcessMemoryInfo(hProccess, &pmc, sizeof(pmc)))
			{
				dwWorkingSetSize = pmc.PagefileUsage;//pmc.WorkingSetSize;
				dwPeakWorkingSetSize = pmc.PeakWorkingSetSize;
				//缺页中断次数:pmc.PageFaultCount
				//使用内存高峰:pmc.PeakWorkingSetSize
				//当前使用的内存: pmc.WorkingSetSize
				//使用页面缓存池高峰: pmc.QuotaPeakPagedPoolUsage
				//使用页面缓存池: pmc.QuotaPagedPoolUsage
				//使用非分页缓存池高峰: pmc.QuotaPeakNonPagedPoolUsage
				//使用非分页缓存池: pmc.QuotaNonPagedPoolUsage
				//使用分页文件:pmc.PagefileUsage
				//使用分页文件的高峰: pmc.PeakPagefileUsage
			}
		}
		else
		{
			DWORD dwMemProcess = 0;
			PSAPI_WORKING_SET_INFORMATION workSet;
			memset(&workSet, 0, sizeof(workSet));
			BOOL bOk = QueryWorkingSet(hProccess, &workSet, sizeof(workSet));
			if (bOk || (!bOk && GetLastError() == ERROR_BAD_LENGTH))
			{
				int nSize = sizeof(workSet.NumberOfEntries) + workSet.NumberOfEntries * sizeof(workSet.WorkingSetInfo);
				char* pBuf = new char[nSize];
				if (pBuf)
				{
					QueryWorkingSet(hProccess, pBuf, nSize);
					PSAPI_WORKING_SET_BLOCK* pFirst = (PSAPI_WORKING_SET_BLOCK*)(pBuf + sizeof(workSet.NumberOfEntries));
					DWORD dwMem = 0;
					for (ULONG_PTR nMemEntryCnt = 0; nMemEntryCnt < workSet.NumberOfEntries; nMemEntryCnt++, pFirst++)
					{
						if (pFirst->Shared == 0) dwMem += si.dwPageSize;
					}
					delete pBuf;
					if(workSet.NumberOfEntries > 0)
					{
						dwMemProcess = dwMem;
						dwWorkingSetSize = dwMemProcess;
						dwPeakWorkingSetSize = dwMemProcess;
					}
				}
			}
			else
			{
				return FALSE;
			}
		}
	}
	else
	{
		int ret = GetLastError();
		return FALSE;
	}
	return TRUE;
}

//获取句柄数
BOOL ProcessInfoCollect::GetHandleCountEx(HANDLE hProccess, DWORD &dwHandles)
{
	return GetProcessHandleCount(hProccess, &dwHandles);
}

//获取线程数
BOOL	ProcessInfoCollect::GetThreadCount(DWORD &dwThreads)
{
	return GetThreadCount(GetCurrentProcessId(), dwThreads);
}
BOOL ProcessInfoCollect::GetThreadCount(DWORD lProcessID, DWORD &dwThreads)
{
	//获取进程信息
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return FALSE;

	BOOL bFind = FALSE;
	char szFilePath[MAX_PATH] = { 0 };
	PROCESSENTRY32 stProcessEntry32 = { 0 };
	stProcessEntry32.dwSize = sizeof(stProcessEntry32);
	BOOL bSucceed = ::Process32First(hProcessSnap, &stProcessEntry32);;
	for (;;)
	{
		if (!bSucceed)
			break;

		if (stProcessEntry32.th32ProcessID == lProcessID)
		{
			dwThreads = stProcessEntry32.cntThreads;
			bFind = TRUE;
			break;
		}
		bSucceed = ::Process32Next(hProcessSnap, &stProcessEntry32);
	}
	::CloseHandle(hProcessSnap);
	return bFind;
}

BOOL ProcessInfoCollect::EnablePrivilege(HANDLE hToken, LPCSTR szPrivName)
{
	TOKEN_PRIVILEGES tkp;//访问令牌权限结构变量
	LUID  luid;//本地唯一标识符结构变量

			   //查询SE_DEBUG_NAME权限所对应的luid值
	if (!LookupPrivilegeValue(NULL, szPrivName, &luid))
	{
		//	TRACE("Lookup Privilege Value Failed...\nErrorCode:%d\n",GetLastError());
		return 0;
	}

	//填充Token_Privileges结构
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Luid = luid;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	//提升权限
	if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
	{
		//		TRACE("Adjust Token Privileges Failed...\nErrorCode:%d\n",GetLastError());
		return 0;
	}

	return(GetLastError() == ERROR_SUCCESS);
}

BOOL ProcessInfoCollect::EnumAllProcess(ProcessInfo *pAll, int & nTotal)
{
	ENUMPROCESS         pEnumProcess;
	ENUMPROCESSMODULES  pEnumProcessModules;
	GETMODULEFILENAMEEX pGetModuleFileNameEx;
	GETMODULEBASENAME   pGetModuleBaseName;

	DWORD dwMajorVersion = 0;
	DWORD dwMinorVersion = 0;
	OSVERSIONINFOEX osver = { 0 };
	osver.dwOSVersionInfoSize = sizeof(osver);
	::GetVersionEx((OSVERSIONINFO*)&osver);
	dwMajorVersion = osver.dwMajorVersion;
	dwMinorVersion = osver.dwMinorVersion;

	HANDLE hToken = NULL;//访问令牌句柄

	DWORD dwPID[MAX_ID] = { 0 };//接授进程ID的数组
	DWORD cbReturn = 0;//返回的字节数
	DWORD dwPCount = 0;//进程数
	DWORD i;
	char  szFileName[MAX_PATH] = { 0 };//文件名
	char  szPathName[MAX_PATH] = { 0 };//路径名
	char  Id[] = "ID", Pid[] = "PID", Exe[] = "ProcessName", Path[] = "Path";

	HANDLE hProcess = NULL; //进程句柄
	HMODULE hModule = NULL;
	HINSTANCE hPsDll = NULL;//实例句柄

	hPsDll = LoadLibrary("PSAPI.DLL");//获得DLL的实例
	if (hPsDll == NULL)
	{
		//FreeLibrary(hPsDll);
		return FALSE;
	}

	//获得函数的地址
	pEnumProcess = (ENUMPROCESS)GetProcAddress(hPsDll, "EnumProcesses");
	pEnumProcessModules = (ENUMPROCESSMODULES)GetProcAddress(hPsDll, "EnumProcessModules");
	pGetModuleFileNameEx = (GETMODULEFILENAMEEX)GetProcAddress(hPsDll, "GetModuleFileNameExA");
	pGetModuleBaseName = (GETMODULEBASENAME)GetProcAddress(hPsDll, "GetModuleBaseNameA");

	if (!(pEnumProcess && pEnumProcessModules && pGetModuleFileNameEx &&pGetModuleBaseName))
	{
		FreeLibrary(hPsDll);
		return FALSE;
	}

	//打开当前进程访问令牌
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		if (EnablePrivilege(hToken, SE_DEBUG_NAME))
		{
			pEnumProcess(dwPID, sizeof(dwPID), &cbReturn);//枚举进程
			dwPCount = cbReturn / sizeof(DWORD);//计算进程/线程总数
			if (dwPCount > nTotal)
			{
				dwPCount = nTotal;
			}
			else
			{
				nTotal = dwPCount;
			}
			for (i = 0; i < dwPCount; i++)
			{
				//打开进程
				hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,//访问权限
					false,//是否允许得到的进程句柄被后创建的子进程继承
					dwPID[i]);//进程ID
				pAll[i].dwPID = dwPID[i];
				if (hProcess)
				{
					//枚举进程模块
					DWORD dwError = 0;
					BOOL bSuccessProcess = pEnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbReturn);
					if (!bSuccessProcess)
					{
						dwError = GetLastError();
					}
					memset(pAll[i].szFileName, 0, sizeof(char)*MAX_PATH);
					memset(pAll[i].szPathName, 0, sizeof(char)*MAX_PATH);
					memset(szFileName, 0, sizeof(szFileName));
					memset(szPathName, 0, sizeof(szPathName));
					if (hModule != NULL)
					{
						//获得进程模块文件名(包含路径)
						if (dwMajorVersion < 5)		//< window2000
						{
							//保存文件名
							//DWORD dwGetModuleBaseName = pGetModuleFileNameEx(hProcess, hModule, szPathName, sizeof(szPathName));
							DWORD dwGetModuleBaseName = GetModuleFileNameEx(hProcess, hModule, szPathName, sizeof(szPathName));
							GetFileNameWithoutExtendName(szPathName, pAll[i].szFileName);
						}
						if (dwMajorVersion == 5)  //xp或Windows Server2003
						{
							GetProcessImageFileName(hProcess, szPathName, sizeof(szPathName));
							GetFileNameWithoutExtendName(szPathName, pAll[i].szFileName);
						}
						else if (osver.dwMajorVersion >= 6)		//win7或win7以上
						{
							DWORD dwPathNameSize = sizeof(szPathName);
							bSuccessProcess = QueryFullProcessImageName(hProcess, 0, szPathName, &dwPathNameSize);
							GetFileNameWithoutExtendName(szPathName, pAll[i].szFileName);
						}
						if (!bSuccessProcess)
						{
							dwError = GetLastError();
						}
						strcpy(pAll[i].szPathName, szPathName);
					}
				}
				if (hProcess)
					CloseHandle(hProcess);
				//if(hModule)
				//	CloseHandle(hModule);
			}
		}
	}

	//关闭句柄和实例
	if (hToken)
		CloseHandle(hToken);
	FreeLibrary(hPsDll);

	return TRUE;
}

/*
功能说明:获取指定进程的所有子进程
参数说明:dwParentPID,父进程ID;m_pChildProcess,[out] 子进程列表;nChildProcessNum,[out]子进程数量
返回值:子进程ID列表
*/
BOOL ProcessInfoCollect::GetChildProcessID(DWORD dwParentPID, DWORD* pChildProcess, int & nChildProcessNum)
{
	//获取进程信息
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return FALSE;

	/*DWORD dwProcessID = 0;*/
	PROCESSENTRY32 stProcessEntry32 = { 0 };
	stProcessEntry32.dwSize = sizeof(stProcessEntry32);
	BOOL bSucceed = ::Process32First(hProcessSnap, &stProcessEntry32);;

	int  i = 0;
	for (;;)
	{
		if (!bSucceed)
			break;

		bSucceed = ::Process32Next(hProcessSnap, &stProcessEntry32);

		if (stProcessEntry32.th32ParentProcessID == dwParentPID)
		{
			if (i < MAX_CHILD_PROCESS_COUNT)
			{
				pChildProcess[i++] = stProcessEntry32.th32ProcessID;
			}
			else
			{
				break;
			}
		}
	}
	::CloseHandle(hProcessSnap);
	nChildProcessNum = i;

	return TRUE;
}

BOOL   CALLBACK   CloseWindowByPID(HWND  hwnd, LPARAM   lParam)
{
	BOOL bRet = FALSE;
	DWORD   dwID;

	GetWindowThreadProcessId(hwnd, &dwID);

	if (dwID == (DWORD)lParam)
	{
		if (PostMessage(hwnd, WM_CLOSE, 0, 0))
		{
			bRet = TRUE;
		}
	}

	return   TRUE;
}

//结束进程
BOOL ProcessInfoCollect::TerminateProcessEx(DWORD   dwPID, DWORD  dwTimeout)
{
	HANDLE       hProc;
	BOOL       bRet = TRUE;

	//   If   we   can 't   open   the   process   with   PROCESS_TERMINATE   rights,
	//   then   we   give   up   immediately.
	hProc = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE,
		dwPID);

	if (hProc == NULL)
	{
		return   FALSE;
	}

	//   WindowEnumCallBack()   posts   WM_CLOSE   to   all   windows   whose   PID
	//   matches  dwPID.
	EnumWindows((WNDENUMPROC)CloseWindowByPID, (LPARAM)dwPID);

	//   Wait   on   the   handle.   If   it   signals,   great.   If   it   times   out,
	//   then   you   kill   it.
	if (WaitForSingleObject(hProc, dwTimeout) != WAIT_OBJECT_0)
	{
		bRet = TerminateProcess(hProc, 0);
		WaitForSingleObject(hProc, dwTimeout);
	}

	CloseHandle(hProc);
	return   bRet;
}

//获取进程所属令牌
HANDLE ProcessInfoCollect::GetProcessToken(DWORD dwPID)
{
	HANDLE       hProc;
	HANDLE       hToken = NULL;

	//   If   we   can 't   open   the   process   with   PROCESS_TERMINATE   rights,
	//   then   we   give   up   immediately. if(!OpenProcessToken(hProc,TOKEN_QUERY|TOKEN_QUERY_SOURCE, &hToken))
	hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
		dwPID);

	if (hProc != NULL)
	{
		if (!OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &hToken))
		{
			DWORD dwRet = GetLastError();
		}
		CloseHandle(hProc);
	}

	return hToken;

}

//创建新进程
BOOL ProcessInfoCollect::CreateNewProcess(LPCSTR pszExeName, WORD wShowWindow, HANDLE &hToken, DWORD & dwProcessID)
{
	if (hToken == NULL)
	{
		BOOL bRet = StartProcess(pszExeName, dwProcessID, wShowWindow);
		if (bRet)
		{
			HANDLE hNewToken = GetProcessToken(dwProcessID);
			if (hToken != NULL)
				CloseHandle(hToken);

			hToken = hNewToken;
		}
		return bRet;
	}
	else
	{
		HANDLE hNewToken = StartProcessBySysService(pszExeName, "", hToken);
		if (hToken != NULL)
			CloseHandle(hToken);

		hToken = hNewToken;
		return TRUE;
	}
}

//根据程序名获取进程ID
DWORD ProcessInfoCollect::GetProcessIDByName(const char* pAppFileName)
{
	//获取进程信息
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return 0;

	DWORD dwProcessID = 0;
	PROCESSENTRY32 stProcessEntry32 = { 0 };
	stProcessEntry32.dwSize = sizeof(stProcessEntry32);
	BOOL bSucceed = ::Process32First(hProcessSnap, &stProcessEntry32);;
	for (;;)
	{
		if (!bSucceed)
			break;

		bSucceed = ::Process32Next(hProcessSnap, &stProcessEntry32);
		if (::_stricmp(stProcessEntry32.szExeFile, pAppFileName) == 0)
		{
			dwProcessID = stProcessEntry32.th32ProcessID;
			break;
		}
	}
	::CloseHandle(hProcessSnap);
	return dwProcessID;
}

//关闭进程
int ProcessInfoCollect::KillProcess(DWORD nProcessID)
{
	HANDLE hProcessHandle = NULL;
	hProcessHandle = ::OpenProcess(PROCESS_TERMINATE, FALSE, nProcessID);
	if (hProcessHandle == NULL)
		return 0;

	//关闭子进程
	DWORD *pChildProcess = new DWORD[MAX_CHILD_PROCESS_COUNT];
	memset(pChildProcess, 0, MAX_CHILD_PROCESS_COUNT);
	int nChildProcessNum = 0;
	BOOL bRet = GetChildProcessID(nProcessID, pChildProcess, nChildProcessNum);
	if (bRet)
	{
		for (int i = 0; i < nChildProcessNum; ++i)
		{
			if (pChildProcess[i] > 0)
			{
				TerminateProcessEx(pChildProcess[i], 200);
			}
		}
	}
	if (pChildProcess != NULL)
	{
		delete[]pChildProcess;
		pChildProcess = NULL;
	}

	bRet = ::TerminateProcess(hProcessHandle, 200);
	if (hProcessHandle != NULL)
		CloseHandle(hProcessHandle);

	return bRet;
}

//启动进程

BOOL ProcessInfoCollect::StartProcess(LPCSTR pAppFullFileName, DWORD &dwProcessID, WORD wShowWindow)
{
	BOOL bRet = FALSE;
	STARTUPINFO   stStartupInformation = { 0 };
	stStartupInformation.cb = sizeof(stStartupInformation);
	stStartupInformation.dwFlags = STARTF_USESHOWWINDOW;
	stStartupInformation.wShowWindow = wShowWindow;//SW_SHOW;

												   //stStartupInformation.lpDesktop="WinSta0\\Winlogon";

	stStartupInformation.lpDesktop = "winsta0\\default";

	PROCESS_INFORMATION   stProcessInformation = { 0 };
	//目录工作路径
	char szProgrammeWorkPath[MAX_PATH] = { 0 };
	::strcpy_s(szProgrammeWorkPath, MAX_PATH - 1, pAppFullFileName);//+1,从c:\..开始
	if (::strchr(szProgrammeWorkPath, ':') != NULL &&
		::strrchr(szProgrammeWorkPath, '\\') != NULL)
	{
		(_tcsrchr(szProgrammeWorkPath, '\\'))[1] = 0;
	}

	bRet = ::CreateProcess((LPTSTR)pAppFullFileName, NULL, NULL, NULL, FALSE, 0, NULL, szProgrammeWorkPath,
		&stStartupInformation, &stProcessInformation);

	dwProcessID = stProcessInformation.dwProcessId;
	if (stProcessInformation.hProcess != NULL)
		CloseHandle(stProcessInformation.hProcess);

	if (stProcessInformation.dwThreadId != NULL)
		CloseHandle(stProcessInformation.hThread);

	return bRet;
}

//启动进程(令牌)
HANDLE ProcessInfoCollect::StartProcessBySysService(const char* pAppFullFileName, const char* pRunParameter, HANDLE hToken)
{
	HANDLE hNewToken = NULL;

	char szSoftWare[1024] = { 0 };
	sprintf_s(szSoftWare, 1024, "\"%s\" %s", pAppFullFileName, pRunParameter);

	STARTUPINFO   stStartupInformation = { 0 };
	stStartupInformation.cb = sizeof(stStartupInformation);
	stStartupInformation.dwFlags = STARTF_USESHOWWINDOW;
	stStartupInformation.wShowWindow = SW_SHOW;
	stStartupInformation.lpDesktop = "winsta0\\default";

	PROCESS_INFORMATION   stProcessInformation = { 0 };

	//目录工作路径
	char szProgrammeWorkPath[MAX_PATH] = { 0 };
	::strcpy_s(szProgrammeWorkPath, MAX_PATH - 1, pAppFullFileName);//+1,从c:\..开始
	if (::strchr(szProgrammeWorkPath, ':') != NULL &&
		::strrchr(szProgrammeWorkPath, '\\') != NULL)
	{
		(_tcsrchr(szProgrammeWorkPath, '\\'))[1] = 0;
	}


	if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
		SecurityImpersonation, TokenPrimary, &hNewToken))
	{
		if (CreateProcessAsUser(hNewToken, NULL,
			szSoftWare, NULL, NULL, FALSE,
			0, NULL, szProgrammeWorkPath, &stStartupInformation, &stProcessInformation))
		{
			if (stProcessInformation.hProcess != NULL)
				CloseHandle(stProcessInformation.hProcess);
			if (stProcessInformation.dwThreadId != NULL)
				CloseHandle(stProcessInformation.hThread);
		}
	}
	return hNewToken;
}

#ifdef StartProcessBySysServiceEx_Flag
BOOL	ProcessInfoCollect::StartProcessBySysServiceEx(const char* pAppFullFileName, const char* pRunParameter)
{
	DWORD dwProcesses = 0;
	BOOL bResult = FALSE;
	char szSoftWare[1024] = { 0 };
	sprintf_s(szSoftWare, 1024, _T("\"%s\" %s"), pAppFullFileName, pRunParameter);

	DWORD dwSid = GetActiveSessionID();
	DWORD dwRet = 0;
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
	if (!WTSQueryUserToken(dwSid, &hPToken))
	{
		PROCESSENTRY32 procEntry;
		DWORD dwPid = 0;
		HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hSnap == INVALID_HANDLE_VALUE)
		{
			return FALSE;
		}

		procEntry.dwSize = sizeof(PROCESSENTRY32);
		if (Process32First(hSnap, &procEntry))
		{
			do
			{
				if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0)
				{
					DWORD exeSessionId = 0;
					if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid)
					{
						dwPid = procEntry.th32ProcessID;
						break;
					}
				}

			} while (Process32Next(hSnap, &procEntry));
		}
		CloseHandle(hSnap);

		// explorer进程不存在
		if (dwPid == 0)
		{
			return FALSE;
		}

		hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
		if (hProcess == NULL)
		{
			return FALSE;
		}

		if (!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P, &hPToken))
		{
			CloseHandle(hProcess);
			return FALSE;
		}
	}

	if (hPToken == NULL)
		return FALSE;

	TOKEN_LINKED_TOKEN admin;
	bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);

	if (!bResult) // vista 以前版本不支持TokenLinkedToken
	{
		TOKEN_PRIVILEGES tp;
		LUID luid;
		if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
		{
			tp.PrivilegeCount = 1;
			tp.Privileges[0].Luid = luid;
			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		}
		//复制token
		DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup);
	}
	else
	{
		hUserTokenDup = admin.LinkedToken;
	}

	LPVOID pEnv = NULL;
	DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;

	// hUserTokenDup为当前登陆用户的令牌
	if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
	{
		//如果传递了环境变量参数,CreateProcessAsUser的
		//dwCreationFlags参数需要加上CREATE_UNICODE_ENVIRONMENT,
		//这是MSDN明确说明的
		dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
	}
	else
	{
		//环境变量创建失败仍然可以创建进程,
		//但会影响到后面的进程获取环境变量内容
		pEnv = NULL;
	}

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	ZeroMemory(&pi, sizeof(pi));
	//USES_CONVERSION;
	bResult = CreateProcessAsUser(
		hUserTokenDup,                     // client's access token
		NULL,    // file to execute
		(LPTSTR)A2T(szSoftWare),                 // command line
		NULL,            // pointer to process SECURITY_ATTRIBUTES
		NULL,               // pointer to thread SECURITY_ATTRIBUTES
		FALSE,              // handles are not inheritable
		dwCreationFlags,     // creation flags
		pEnv,               // pointer to new environment block
		NULL,               // name of current directory
		&si,               // pointer to STARTUPINFO structure
		&pi                // receives information about new process
	);


	if (pi.hProcess)
	{
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
	}

	if (hUserTokenDup != NULL)
		CloseHandle(hUserTokenDup);
	if (hProcess != NULL)
		CloseHandle(hProcess);
	if (hPToken != NULL)
		CloseHandle(hPToken);
	if (pEnv != NULL)
		DestroyEnvironmentBlock(pEnv);

	return TRUE;
}
#endif

//调用方法

ProcessInfoCollect picProcessInfoCollect;
int nRet = 0;    
DWORD             nMemoryUsed;                    //内存使用(Byte)    
DWORD            nVirtualMemoryUsed;                //虚拟内存使用(Byte)    
DWORD            nHandleNumber;                    //句柄数量
DWORD dwCurrentProcessThreadCount;        //线程数量    
ULONGLONG ullIo_read_bytes;                        //IO读字节数    
ULONGLONG ullIo_write_bytes;                    //IO写字节数    
ULONGLONG ullIo_wct;                            //IO写次数    
ULONGLONG ullIo_rct;                            //IO读次数        
double dCPUUserRate = 0;                        //CPU使用的百分比        
picProcessInfoCollect.GetCPUUserRate(dCPUUserRate);    
picProcessInfoCollect.GetMemoryUsed(nVirtualMemoryUsed, nMemoryUsed);    
nVirtualMemoryUsed = nVirtualMemoryUsed;    
nMemoryUsed = nMemoryUsed;    
picProcessInfoCollect.GetThreadCount(dwCurrentProcessThreadCount);    
picProcessInfoCollect.GetHandleCount(nHandleNumber);    
picProcessInfoCollect.GetIOBytes(&ullIo_read_bytes, &ullIo_write_bytes, &ullIo_wct, &ullIo_rct);

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byxdaz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值