关闭进程需要特定权限,如果你程序权限不够也会导致关闭进程失败。关闭进程树,需要遍历给定进程下的所有子进程,这个过程可以用并查集来做。

    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;

}
View Code

 

      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;
}