web-dev-qa-db-fra.com

Comment un processus Win32 peut-il obtenir le pid de son parent?

Je passe actuellement le pid sur la ligne de commande à l'enfant, mais existe-t-il un moyen de le faire dans l'API Win32? Sinon, quelqu'un peut-il atténuer ma crainte que le pid que je passe pourrait appartenir à un autre processus après un certain temps si le parent est décédé?

34
twk

Notez que si le processus parent se termine, il est très possible et même probable que le PID soit réutilisé pour un autre processus. Il s'agit d'une opération Windows standard.

Donc, pour être sûr, une fois que vous avez reçu l'ID du parent et que vous êtes sûr qu'il s'agit bien de votre parent, vous devez lui ouvrir un handle et l'utiliser.

11
shoosh

Juste au cas où quelqu'un d'autre rencontre cette question et cherche un exemple de code, j'ai dû le faire récemment pour un projet de bibliothèque Python sur lequel je travaille. Voici le code de test/exemple que je est venu avec:

#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);
}
50
Jay
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;
}
20
Napalm

Une meilleure façon de procéder consiste à appeler DuplicateHandle() pour créer un doublon héritable de votre descripteur de processus. Créez ensuite le processus enfant et passez la valeur du handle sur la ligne de commande. Close le handle dupliqué dans le processus parent. Lorsque l'enfant aura terminé, il devra également Close sa copie.

20
Peter Ruderman

"Alternativement, quelqu'un peut-il atténuer ma crainte que le pid que je passe pourrait appartenir à un autre processus après un certain temps si le parent est décédé?"

Oui, le PID peut être réutilisé. Contrairement à UNIX, Windows ne gère pas une arborescence de relations parent-enfant solide.

3
user15071