后台服务要启动一系列的子进程。当后台服务 关闭时需要将子进程进行关闭。但是在关闭子进程时为了避免错杀漏杀可以通过进程的父进程来判断。
首先获得本服务的进程号
使用 GetCurrentProcessId 获得当前进程的ID
使用 CreateToolhelp32Snapshot 、Process32First 、Process32Next 来枚举当前所有进程,判断当前被枚举的进程的父进程是否与当前进程的ID相同。以此来判断是否该关闭该进程。
示例代码:(从类中直接摘出)
.h文件
// add by loken 20071108
#ifndef _PROSTATUS_H
#define _PROSTATUS_H
typedef struct TProcessStatus{
TCHAR wsProcessName[128*2];
DWORD dwPID;
DWORD dwParantPID;
}stProcessStatus;
#endif
stProcessStatus ProStatus[256];
int iEnumCnt;
DWORD dwCurrProID;
int ProcessList();
int TerminateProcessFromId(DWORD dwId);
// end loken add
int CSpService::ProcessList(){
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
int count=0;
HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap==INVALID_HANDLE_VALUE){
wprintf(_T("CreateToolhelp32Snapshot调用失败!"));
return -1;
}
BOOL bMore=::Process32First(hProcessSnap,&pe32);
wprintf(_T("%20s/t%10s/t%10s/n"),_T("进程名"),_T("PID"),_T("ParentID"));
ZeroMemory(ProStatus,sizeof(ProStatus));
while(bMore){
count++;
wsprintf(ProStatus[iEnumCnt].wsProcessName,_T("%s"),pe32.szExeFile);
ProStatus[iEnumCnt].dwPID = pe32.th32ProcessID;
ProStatus[iEnumCnt].dwParantPID = pe32.th32ParentProcessID;
bMore=::Process32Next(hProcessSnap,&pe32);
wprintf(_T("%s/t%ld/t%ld/n"),pe32.szExeFile,pe32.th32ProcessID,pe32.th32ParentProcessID);
iEnumCnt++;
}
::CloseHandle(hProcessSnap);
// get Current Process ID
dwCurrProID = GetCurrentProcessId();
return 0;
}
int CSpService::TerminateProcessFromId(DWORD dwId)
{
BOOL bRet=FALSE;
HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwId);
if(hProcess!=NULL)
{
bRet=::TerminateProcess(hProcess,0);
}
::CloseHandle(hProcess);
if(bRet)
printf("%d 进程结束成功....../n/n/n/n",dwId);
else
printf("%d 进程结束失败....../n/n/n/n",dwId);
return 0;
}
关闭:
for (int i=0; i<iEnumCnt; i++){
if (ProStatus[i].dwParantPID == dwCurrProID)
TerminateProcessFromId(ProStatus[i].dwPID);
}