windows下關閉程序樹
關閉程序需要特定許可權,如果你程式許可權不夠也會導致關閉程序失敗。關閉程序樹,需要遍歷給定程序下的所有子程序,這個過程可以用並查集來做。
1、編寫獲取程序父程序的程式碼
#define ProcessBasicInformation 0 typedef struct { DWORD ExitStatus; DWORD PebBaseAddress; DWORD AffinityMask; DWORD BasePriority; ULONG UniqueProcessId; ULONG InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION; typedef LONG (__stdcallView Code*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; }