1. 程式人生 > >windows下關閉程序樹

windows下關閉程序樹

  關閉程序需要特定許可權,如果你程式許可權不夠也會導致關閉程序失敗。關閉程序樹,需要遍歷給定程序下的所有子程序,這個過程可以用並查集來做。

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