zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/jlyg/p/10100597.html
Copyright © 2011-2022 走看看