2011-03-16 174 views
1

我使用CreateProcess API创建子进程。从子进程中,我需要获取父进程ID。从子进程获取父进程ID

如果我的进程树有一个孩子和一个大孩子。我需要从大孩子那里获取最顶级父母的进程ID。

回答

5

您应该使用Native API和GetProcAddress来查找NtQueryInformationProcess的地址。

typedef struct _PROCESS_BASIC_INFORMATION 
{ 
    NTSTATUS ExitStatus; 
    PPEB PebBaseAddress; 
    ULONG_PTR AffinityMask; 
    KPRIORITY BasePriority; 
    HANDLE UniqueProcessId; 
    HANDLE InheritedFromUniqueProcessId; 
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; 

NTSYSCALLAPI 
NTSTATUS 
NTAPI 
NtQueryInformationProcess(
    __in HANDLE ProcessHandle, 
    __in PROCESS_INFORMATION_CLASS ProcessInformationClass, 
    __out_bcount(ProcessInformationLength) PVOID ProcessInformation, 
    __in ULONG ProcessInformationLength, 
    __out_opt PULONG ReturnLength 
    ); 

PROCESS_BASIC_INFORMATION basicInfo; 

NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &basicInfo, sizeof(basicInfo), NULL); 
// My parent PID (*) is in basicInfo.InheritedFromUniqueProcessId 

为了让祖父母PID,打开使用父PI​​D父进程和父进程再次调用NtQueryInformationProcess

注意 - 严格来说,父进程(创建子进程的进程)实际上并未被记录。 InheritedFromUniqueProcessId只是为您提供了继承属性的过程。但这很少是一个问题。

或者,如果您不喜欢Native API,请使用CreateToolhelp32SnapshotTH32CS_SNAPPROCESS,它会为您提供所需的信息,不同之处在于您必须搜索整个列表。

+0

在MSDN上,NtQueryInformationProcess文档提到了PROCESS_BASIC_INFORMATION,但它没有InheritedFromUniqueProcessId。这是特定于某个Windows版本吗? https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280%28v=vs.85%29.aspx – chilemagic 2015-10-28 14:06:56

0

AFAIK,没有标准的方法来找到当前进程的祖父进程。找到父母的过程是正常的,但不是祖父母。如果你真的需要这些信息,那么父母的过程必须教育他们的孩子关于父母自己的父母过程 - 就像父母必须教孩子一般关于生活的真实生活。

通信如何发生取决于进程是仅仅复制自己(分叉)还是它也在执行其他进程。如果这些过程只是分叉,那么父类只需要设置一个适当的变量。如果进程正在执行其他程序,则需要查看环境变量或命令行参数以中继该信息。

+0

如果我离开祖父母,只是想找到父母的身份证号码,我该怎么办。 – 2011-03-16 07:15:44

+0

@Beetles:在Unix中,你会使用'getppid()'。如果你的Windows机器上有Unix服务,那么你也可以在那里使用它。否则,你可能会发现'_getppid()'可用并且可行,但可能还有一个原生WinAPI调用可以完成同样的工作 - 我不知道它是什么,我的Google-fu似乎抛弃了我。 – 2011-03-16 16:34:12

1

wj32的答案应该做你需要的,但我想我会提到另一种方式,以防其他人需要一个不同级别的祖先。您还可以拍摄快照列举流程树并浏览祖先,直到达到您想要达到的任何级别,如here所述。

下面的示例获取的父进程的进程ID(该过程开始的当前一个):

// Speed up build process with minimal headers. 
#define WIN32_LEAN_AND_MEAN 
#define VC_EXTRALEAN 

#include <tchar.h> 
#include <windows.h> 
#include <tlhelp32.h> 
#include <stdio.h> 

/* Macros for prettier code. */ 
#ifndef MAX_PATH 
# define MAX_PATH _MAX_PATH 
#endif 

// Search each process in the snapshot for id. 
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe) 
{ 
    BOOL fOk; 
    ppe->dwSize = sizeof(PROCESSENTRY32); 
    for (fOk = Process32First(snap, ppe); fOk; fOk = Process32Next(snap, ppe)) 
     if (ppe->th32ProcessID == id) 
      break; 
    return fOk; 
} 

// Obtain the process and thread identifiers of the parent process. 
BOOL ParentProcess(LPPROCESS_INFORMATION ppi) 
{ 
    HANDLE hSnap; 
    PROCESSENTRY32 pe; 
    THREADENTRY32 te; 
    DWORD id = GetCurrentProcessId(); 
    BOOL fOk; 

    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD, id); 

    if (hSnap == INVALID_HANDLE_VALUE) 
     return FALSE; 

    FindProcessID(hSnap, id, &pe); 
    if (!FindProcessID(hSnap, pe.th32ParentProcessID, &pe)) 
    { 
     CloseHandle(hSnap); 
     return FALSE; 
    } 

    te.dwSize = sizeof(te); 
    for (fOk = Thread32First(hSnap, &te); fOk; fOk = Thread32Next(hSnap, &te)) 
     if (te.th32OwnerProcessID == pe.th32ProcessID) 
      break; 

    CloseHandle(hSnap); 

    ppi->dwProcessId = pe.th32ProcessID; 
    ppi->dwThreadId = te.th32ThreadID; 

    return fOk; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    PROCESS_INFORMATION parentInformation; 
    if(!ParentProcess(&parentInformation)) { 
     _tprintf(TEXT("Fatal: Could not get parent information.\n")); 
     return 1; 
    } 
    _tprintf(TEXT("Parent Process ID: %ul\n"), parentInformation.dwProcessId); 
    return 0; 
} 
0

这里是一个C程序获取父进程ID(与上仅处理一个环路总)。 函数GetParentProcessId()在其输出参数“parent_process_id”中返回Windows父进程标识。

#include <windows.h> 
#include <tlhelp32.h> 
#include <stdio.h> 

// Find a process with a given id in a snapshot 
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe) 
{ 
    BOOL res; 
    ppe->dwSize = sizeof(PROCESSENTRY32); // (mandatory) 
    res = Process32First(snap, ppe); 
    while (res) { 
    if (ppe->th32ProcessID == id) { 
     return TRUE; 
    } 
    res = Process32Next(snap, ppe); 
    } 
    return FALSE; 
} 

// Get the parent process id of the current process 
BOOL GetParentProcessId(DWORD* parent_process_id) 
{ 
    HANDLE hSnap; 
    PROCESSENTRY32 pe; 
    DWORD current_pid = GetCurrentProcessId(); 

    // Take a snapshot of all Windows processes 
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    if (INVALID_HANDLE_VALUE == hSnap) { 
    return FALSE; 
    } 

    // Find the current process in the snapshot 
    if (!FindProcessID(hSnap, current_pid, &pe)) { 
    return FALSE; 
    } 

    // Close the snapshot 
    if (!CloseHandle(hSnap)) { 
    return FALSE;  
    } 

    *parent_process_id = pe.th32ParentProcessID; 
    return TRUE; 
}