// 简单实现杀死进程树(一层树),即传入一个进程ID, 该进程的子进程将都被强制杀掉。
父进程1
+---------子进程1
+---------子进程2
+---------子进程3
父进程2
+---------子进程4
+---------子进程5
父进程3
+---------子进程6
+---------子进程7
假如我们的入参是
父进程2,那么
子进程4,
子进程5就被删除。
该例子仅用于说明如何获取进程树的snapshot,及如何杀进程:
BOOL KillProcessModule ( int parentPid)
{
PROCESSENTRY32 pe32;
//在使用这个结构前,先设置它的大小
pe32.dwSize = sizeof(pe32);
//给系统内所有的进程拍个快照
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
qDebug( "CreateToolhelp32Snapshot fail." );
return -1;
}
//遍历进程快照,轮流显示每个进程的信息
BOOL killSuccess = FALSE;
BOOL bMore = ::Process32First(hProcessSnap,&pe32);
while (bMore)
{
QString name = QString::fromWCharArray(pe32.szExeFile);
qDebug( "PRO NAME: %s", name.toLatin1().data());
qDebug( "PRO PID:%d", pe32.th32ProcessID);
qDebug( "PRO PPID:%d", pe32.th32ParentProcessID);
if(parentPid == pe32.th32ParentProcessID){
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE,FALSE, pe32.th32ProcessID);
if(TerminateProcess(hProcess,0)){
killSuccess = TRUE;
}
break;
}
bMore = ::Process32Next(hProcessSnap,&pe32);
}
//不要忘记清除掉snapshot对象
::CloseHandle(hProcessSnap);
return killSuccess;
}
// 完整实现杀死进程树(多层树)
进程1
+---------进程1
+---------进程2
+---------进程3
进程2
+---------进程4
+---------进程5
+---------进程8
+---------进程9
进程3
+---------进程6
+---------进程10
+---------进程11
+---------进程7
假如我们的入参是
进程2,那么
进程8,
子进程9,进程4进程4就被删除。
该例子是完整的实现,并加入了获取特权(
Privileges
)的逻辑:
bool KillMakeSure(DWORD processID){
bool bResult = true ;
HANDLE hProcess;
HANDLE hProcessToken;
TOKEN_PRIVILEGES tp;
LUID luid;
QString strCmd = QString( "echo start to kill %1 >> %systemdrive%\\Users\\%username%\\Desktop\\TEST_LOG.log").arg(QString::number(processID, 10) );
system(strCmd.toUtf8().data());
if (processID == 0){
//! input process id error
return false ;
}
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hProcessToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Adjust Token privileges */
if (! AdjustTokenPrivileges(
hProcessToken,
FALSE,
&tp,
sizeof (tp),
NULL,
NULL ) )
{
CloseHandle (hProcessToken);
return false ;
}
// open handle of target process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if ( (hProcess == NULL) ){
//! open failed
bResult = false ;
}
if (TerminateProcess(hProcess, 0xf291)) {
//! kill success
bResult = true ;
}
else {
//! kill failed
bResult = false ;
}
CloseHandle(hProcessToken);
CloseHandle(hProcess);
if (bResult){
strCmd = QString( "echo success kill %1 >> %systemdrive%\\Users\\%username%\\Desktop\\TEST_LOG.log").arg(QString::number(processID, 10) );
system(strCmd.toUtf8().data());
} else {
strCmd = QString( "echo failed kill %1 >> %systemdrive%\\Users\\%username%\\Desktop\\TEST_LOG.log").arg(QString::number(processID, 10) );
system(strCmd.toUtf8().data());
}
return bResult;
}
void KillRecursively(DWORD processID, ProcTree procTree, bool killProcess)
{
QSet<DWORD> children = procTree[processID];
foreach(DWORD childID, children)
{
KillRecursively(childID, procTree);
}
if (!killProcess) return ;
KillMakeSure(processID);
}
void KillChildren()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
return;
}
pe32.dwSize = sizeof( PROCESSENTRY32 );
if( !Process32First( hProcessSnap, &pe32 ) )
{
CloseHandle( hProcessSnap ); // clean the snapshot object
return;
}
ProcTree procTree;
do
{
procTree[pe32.th32ParentProcessID] << pe32.th32ProcessID;
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
KillRecursively( this->pid()->dwProcessId, procTree, false);
}