最近一个MFC项目里有个需求是:需要根据一个进程名称获取其父进程名称。于是查了些资料整理出来份代码,并进行了些测试结果OK。直接拿来即可当工具类使用,以下贴上代码:
头文件GetProcessInfo.h:
#pragma once
#include <wtypes.h>
#define ProcessBasicInformation 0
typedef struct
{
DWORD ExitStatus;
DWORD PebBaseAddress;
DWORD AffinityMask;
DWORD BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
class GetProcessInfo
{
public:
GetProcessInfo(void);
~GetProcessInfo(void);
//通过进程名称获取进程ID,同时也可通过传个引用参数获取到父进程ID,同下面GetParentProcessId获取的结果一致
DWORD GetProcessIdFromName(CString strProcessName, DWORD &dwParentProcessId);
//通过子进程ID获取其父进程ID
DWORD GetParentProcessId(DWORD dwChildProcessId);
//通过进程ID获取进程名称
CString GetProcessNameFromId(DWORD dwProcessId);
};
源文件GetProcessInfo.cpp内容:
#include "stdafx.h"
#include "GetProcessInfo.h"
#include <tlhelp32.h>
#pragma comment (lib,"Psapi.lib")
#include <Psapi.h>
GetProcessInfo :: GetProcessInfo(void)
{
}
GetProcessInfo :: ~GetProcessInfo(void)
{
}
DWORD GetProcessInfo :: GetProcessIdFromName(CString strProcessName, DWORD &dwParentProcessId)
{
DWORD dwProcessID =0;
//进行一个进程快照
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
OutputDebugString(_T("进程快照失败!"));
return FALSE;
}
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
BOOL bProcess = Process32First(hProcessSnap,&pe);
while (bProcess)
{
if (strProcessName.CompareNoCase(pe.szExeFile) == 0)
{
dwProcessID = pe.th32ProcessID;
dwParentProcessId = pe.th32ParentProcessID; //pe结构中包含有父进程的ID
}
bProcess = Process32Next(hProcessSnap,&pe);
}
CloseHandle(hProcessSnap);
return dwProcessID;
}
DWORD GetProcessInfo :: GetParentProcessId(DWORD dwChildProcessId)
{
//NtQueryInformationProcess函数的使用需要加载进ntdll.dll
PROCNTQSIP NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationProcess");
if(!NtQueryInformationProcess)
{
OutputDebugString(_T("ntdll.dll中检索NtQueryInformationProcess失败!"));
}
DWORD dwParentProcessId = 0;
LONG status;
PROCESS_BASIC_INFORMATION pbi;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwChildProcessId);
if (!hProcess)
{
OutputDebugString(_T("OpenProcess Error!"));
return FALSE;
}
status = NtQueryInformationProcess( hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (!status)
{
dwParentProcessId = (DWORD)pbi.InheritedFromUniqueProcessId;
CString strParentID;
strParentID.Format(_T("%d"), dwParentProcessId);
OutputDebugString(_T("ParentProcessID:")+strParentID);
}
return dwParentProcessId;
}
CString GetProcessInfo :: GetProcessNameFromId(DWORD dwProcessId)
{
CString strProcessName;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwProcessId);
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, strProcessName.GetBuffer(MAX_PATH), MAX_PATH);
strProcessName.ReleaseBuffer();
}
}
return strProcessName;
}
用到时,直接将该头文件和源文件引入项目,在需要用到的地方定义一个GetProcessInfo对象,然后传参数调用其相关函数即可。