首先,看看Win32 Job API。一種功能是能夠自動終止屬於同一作業的所有進程。請參閱TerminateJobObject API。
編輯:陳先生剛纔博客有關這個確切的主題。 Destroying all child processes (and grandchildren) when the parent exits
然後,你的問題。你可以爲所有當前正在運行的進程構建一個std :: map,關鍵是PID,值是子進程的std :: vector。然後你可以在地圖上遞歸來終止一個進程和他所有的孩子。
// KillChildren.cpp
// Usage: pass a PID a argument
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
#include <map>
typedef std::vector<DWORD> VEC_CHILDS;
typedef VEC_CHILDS::iterator IT_CHILDS;
typedef std::map<DWORD, VEC_CHILDS> MAP_PIDS;
typedef MAP_PIDS::iterator IT_PIDS;
void KillProcess(DWORD dwPID) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, dwPID);
if (hProcess == NULL) {
printf("Cant't OpenProcess for PID %u, Reason %u\n", dwPID, GetLastError());
return;
}
BOOL bWin32Success = TerminateProcess(hProcess, 0);
if (bWin32Success == 0) {
printf("Cant't TerminateProcess for PID %u, Reason %u\n",
dwPID, GetLastError());
} else {
DWORD dwRetVal = WaitForSingleObject(hProcess, 2000);
if (dwRetVal != WAIT_OBJECT_0) {
printf("Failed to Wait for Process Termination for PID %u,"
"RetVal %u Reason %u\n", dwPID, dwRetVal, GetLastError());
} else {
printf("Process %u Terminated\n", dwPID);
}
}
CloseHandle(hProcess);
}
void KillChilds(DWORD dwParentPID, MAP_PIDS & mPids) {
IT_PIDS it = mPids.find(dwParentPID);
if (it == mPids.end()) return;
VEC_CHILDS & vChilds = it->second;
for (IT_CHILDS itChild = vChilds.begin(); itChild != vChilds.end(); ++itChild) {
KillChilds(*itChild, mPids);
}
KillProcess(dwParentPID);
}
// usage: PID as first arg
int main(int argc, char* argv[]) {
if (argc <= 1) return -1;
DWORD dwPID = atoi(argv[ 1 ]);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return -1;
// build PID list with children
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return -1;
}
MAP_PIDS mPids;
do {
// Add as a Parent, with no child, yet, if not already done
IT_PIDS it = mPids.find(pe32.th32ProcessID);
if (it == mPids.end()) mPids[ pe32.th32ProcessID ] = VEC_CHILDS();
// Process the Parent
it = mPids.find(pe32.th32ParentProcessID);
if (it == mPids.end()) {
// unknown parent, add it with one child
VEC_CHILDS vChilds;
vChilds.push_back(pe32.th32ProcessID);
mPids[ pe32.th32ParentProcessID ] = vChilds;
} else {
// Parent already here, add one more child
it->second.push_back(pe32.th32ProcessID);
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
KillChilds(dwPID, mPids);
return 0;
}
如果你想測試上面的程序,這裏是一個小的進程樹生成要殺死所有的子進程時,(因爲)你的第一個進程終止
// CreateChildren.cpp
// beware, messing may be 'fork bombing'
#include <Windows.h>
int main(int argc, char* argv[]) {
srand(GetTickCount());
// always childs if args
if (argc == 0) {
int iRandom = rand();
if (iRandom % 3) Sleep(INFINITE);
}
char szFullExeName[ MAX_PATH ];
DWORD dwCopied = GetModuleFileName(NULL, szFullExeName, sizeof(szFullExeName));
if (dwCopied == 0) return -1;
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
int ChildCount = rand() % 3;
while (ChildCount--) {
BOOL bWin32Success = CreateProcess(szFullExeName, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (bWin32Success) {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
}
Sleep(INFINITE);
return 0;
}
做什麼? – manuell
我的回答有幫助嗎? – manuell
嗨@quanrock請給予反饋。你有沒有設法使用喬布斯,或使用我的代碼? – manuell