繁体   English   中英

从子进程中获取父进程ID

[英]Fetching parent process Id from child process

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

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

您应该使用本机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仅向您提供继承属性的过程。 但这很少是一个问题。

或者,如果您不喜欢本机API, 则将CreateToolhelp32SnapshotTH32CS_SNAPPROCESS 结合使用,这将为您提供所需的信息,但您必须在列表中进行搜索。

wj32的答案应该可以满足您的需求,但是我想我提到了另一种方法,以防其他人需要不同级别的祖先。 您还可以拍摄快照以枚举过程树并浏览祖先,直到达到此处要达到的任何级别。

以下示例获取父流程的流程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;
}

这是一个C程序,用于获取父进程ID(总共只有一个循环)。 函数GetParentProcessId()在其out参数“ parent_process_id”中返回Windows父进程ID。

#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;
}

AFAIK,没有找到当前流程的祖父母流程的标准方法。 寻找父进程是正常的,但祖父母却不然。 如果您确实需要这些信息,那么家长流程必须教育孩子有关家长自己的家长流程的知识-就像现实生活中那样,家长通常必须向孩子传授有关生活的知识。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM