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;
    }
  • 相关阅读:
    英文半字节压缩编码技术
    博弈翻硬币游戏
    POJ 2015 Permutation Code
    8051、ARM和DSP指令周期的测试与分析
    Huffman编码
    CentOS 命令提示符颜色及样式详解
    JAVA程序员面试32问
    面向抽象编程:接口和抽象类
    初学实用:实例讲解Java中的接口的作用
    C#和Java的区别
  • 原文地址:https://www.cnblogs.com/jlyg/p/10100597.html
Copyright © 2011-2022 走看看