Как процесс Win32 может получить pid своего родителя? - PullRequest
32 голосов
/ 09 октября 2008

В настоящее время я передаю pid в командной строке дочернему элементу, но есть ли способ сделать это в Win32 API? В качестве альтернативы, может ли кто-нибудь ослабить мой страх, что передаваемый мною pid может принадлежать другому процессу через некоторое время, если родитель умер?

Ответы [ 5 ]

50 голосов
/ 17 февраля 2009

На тот случай, если кто-нибудь еще столкнется с этим вопросом и ищет пример кода, мне пришлось сделать это недавно для проекта библиотеки Python, над которым я работаю. Вот тест / пример кода, который я придумал:

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

int main(int argc, char *argv[]) 
{
    int pid = -1;
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(PROCESSENTRY32);

    //assume first arg is the PID to get the PPID for, or use own PID
    if (argc > 1) {
        pid = atoi(argv[1]);
    } else {
        pid = GetCurrentProcessId();
    }

    if( Process32First(h, &pe)) {
        do {
            if (pe.th32ProcessID == pid) {
                printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID);
            }
        } while( Process32Next(h, &pe));
    }

    CloseHandle(h);
}
20 голосов
/ 11 июня 2009

Лучший способ сделать это - вызвать DuplicateHandle() для создания наследуемой копии вашего дескриптора процесса. Затем создайте дочерний процесс и передайте значение дескриптора в командной строке. Close Дублированный дескриптор в родительском процессе. Когда ребенок закончит, ему потребуется также Close его копия.

19 голосов
/ 29 июня 2010
ULONG_PTR GetParentProcessId() // By Napalm @ NetCore2K
{
 ULONG_PTR pbi[6];
 ULONG ulSize = 0;
 LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle, ULONG ProcessInformationClass,
  PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); 
 *(FARPROC *)&NtQueryInformationProcess = 
  GetProcAddress(LoadLibraryA("NTDLL.DLL"), "NtQueryInformationProcess");
 if(NtQueryInformationProcess){
  if(NtQueryInformationProcess(GetCurrentProcess(), 0,
    &pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi))
     return pbi[5];
 }
 return (ULONG_PTR)-1;
}
10 голосов
/ 09 октября 2008

Обратите внимание, что если родительский процесс завершается, это очень возможно и даже вероятно, что PID будет повторно использован для другого процесса. Это стандартная операция Windows.

Поэтому, чтобы быть уверенным, как только вы получите идентификатор родителя и уверены, что это действительно ваш родитель, вы должны открыть для него дескриптор и использовать его.

2 голосов
/ 09 октября 2008

"В качестве альтернативы, кто-то может ослабить мой страх, что я сдаю пид может принадлежать другому процессу через некоторое время, если родитель умер? "

Да, PID можно использовать повторно. В отличие от UNIX, Windows не поддерживает сильное дерево родительско-дочерних отношений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...