关闭进程需要特定权限,如果你程序权限不够也会导致关闭进程失败。关闭进程树,需要遍历给定进程下的所有子进程,这个过程可以用并查集来做。
1、编写获取进程父进程的代码
#define ProcessBasicInformation 0 typedef struct { DWORD ExitStatus; DWORD PebBaseAddress; DWORD AffinityMask; DWORD BasePriority; ULONG UniqueProcessId; ULONG InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION; typedef LONG (__stdcall *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG); DWORD GetParentProcessID(DWORD dwProcessId) { LONG status; DWORD dwParentPID = (DWORD)-1; HANDLE hProcess; PROCESS_BASIC_INFORMATION pbi; PROCNTQSIP NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress( GetModuleHandle("ntdll"), "NtQueryInformationProcess"); if(NULL == NtQueryInformationProcess) { return (DWORD)-1; } // Get process handle hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE, dwProcessId); if (!hProcess) { return (DWORD)-1; } // Retrieve information status = NtQueryInformationProcess( hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL ); // Copy parent Id on success if (!status) { dwParentPID = pbi.InheritedFromUniqueProcessId; } CloseHandle (hProcess); return dwParentPID; }
2、并查集find的代码
DWORD FindParentPID(std::map<DWORD,DWORD>& mapPPID,DWORD dwParentPID) { if(mapPPID.find(dwParentPID) == mapPPID.end() || mapPPID[dwParentPID]==dwParentPID) return dwParentPID; DWORD root = FindParentPID(mapPPID,mapPPID[dwParentPID]); mapPPID[dwParentPID] = root; return root; }
3、通过进程id来结束进程树代码
BOOL StopProcessTree(DWORD dwProcessID)
{
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 info;
info.dwSize = sizeof(PROCESSENTRY32);
Process32First(handle, &info);
std::map<DWORD,DWORD> mapPID; //key为进程id,val为根进程id。
while (Process32Next(handle, &info) != FALSE)
{
DWORD dwPPID= GetParentProcessID(info.th32ProcessID); //找直接上一级的父进程
if(info.th32ProcessID == dwProcessID)
{
mapPID[dwProcessID] = dwProcessID;
}
else if(dwPPID != (DWORD)-1)
{
mapPID[info.th32ProcessID] = dwPPID;
}
}
::CloseHandle(handle);
BOOL bRet = TRUE;
//使用并查集原理优化查询特定进程的进程树效率。
for(std::map<DWORD,DWORD>::iterator iter = mapPID.begin();iter != mapPID.end();iter++)
{
DWORD dwTempPID = iter->first;
if(FindParentPID(mapPID,dwTempPID)==dwProcessID)
{
HANDLE hProcess= OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTempPID);
bRet = TerminateProcess(hProcess,0)?bRet:FALSE;
::CloseHandle(hProcess);
}
}
return bRet;
}
4、通过进程名来结束进程树
BOOL StopProcessByName(LPCTSTR pszProcessName) { HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); PROCESSENTRY32 info; info.dwSize = sizeof(PROCESSENTRY32); Process32First(handle, &info); BOOL bRet = TRUE; while (Process32Next(handle, &info) != FALSE) { CString csProcessName = pszProcessName; CString csExeFile = info.szExeFile; if(csExeFile.CompareNoCase(csProcessName)==0) { StopProcessTree(info.th32ProcessID); break; } } ::CloseHandle(handle); return bRet; }