2011-03-16 244 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; 
}