Arborescence des processus : savoir qui a lancé qui et terminer l'arborescence d'un processus

Description

Ce code permet de savoir quel exe a lancé quel exe : l'arborescence des processus. Il permet aussi de terminer soit un processus particulier, soit une arborescence de processus (du parent vers les enfants ou des enfants vers le parent)

Il permet aussi de connaître le chemin complet du programme qui a lancé le votre

Certains processus peuvent apparaitre sans parent si celui-ci n'est plus en exécution. Certains processus comme Csrss.exe (le sous système Win32) interdit son accès par du code ring3...il ne peut donc pas être killé (c'est aussi bien sinon écran bleu)...on ne peut pas avoir son chemin complet non plus (mis juste son nom.exe)

Source / Exemple :


'inclure les processus dans la vue
Private Const TH32CS_SNAPPROCESS As Long = &H2
'des infos sur un processus
Public Type PROCESSENTRY32
    dwSize As Long                  'taille de cette structure (à initialiser avant l'appel à Process32First ou Process32Next)
    cntUsage As Long                'nombre de handles du processus ouverts
    th32ProcessID As Long           'ID du processus
    th32DefaultHeapID As Long       'interne à windows
    th32ModuleID As Long            'interne à windows
    cntThreads As Long              'nombre de threads du processus
    th32ParentProcessID As Long     'ID du processus parent
    pcPriClassBase As Long          'classe de priorité de base
    dwFlags As Long                 'réservé
    szExeFile As String * 260       'NT/2000/XP : nom du fichier Exe (sans le chemin)
                                    '9x/ME : chemin et nom du fichier Exe
End Type
'crée une vue des processus du système
'renvoie un handle à fermer avec CloseHandle quand on en a plus besoin
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
'renvoie le premier processus de la liste
Private Declare Function Process32First Lib "kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
'renvoie les processus suivants
Private Declare Function Process32Next Lib "kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
'renvoie l'ID du processus appelant
Private Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Long
'ferme un handle
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long

'NT/2000/XP/2003
Private Const VER_PLATFORM_WIN32_NT As Long = 2
'des infos sur la version de windows
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long     'taille de cette structure (à initialiser avant appel à GetVersionEx)
    dwMajorVersion As Long          'numéro majeur
    dwMinorVersion As Long          'numéro mineur
    dwBuildNumber As Long           'numéro de compilation
    dwPlatformId As Long            '3.x/9x Me/NT 2000 XP 2003
    szCSDVersion As String * 128 ' Maintenance string for PSS usage
End Type
'renvoie la version de windows
Private Declare Function GetVersionEx Lib "kernel32.dll" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long

'accès en lecture de la mémoire
Private Const PROCESS_VM_READ As Long = (&H10)
'accès en collecte d'informations
Private Const PROCESS_QUERY_INFORMATION As Long = (&H400)
'obtient un handle vers un processus par son PID
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

'NT/2000/XP/2003... seulement
'renvoie le nom du module "hModule" du processus "hProcess" (ouvert avec OpenProcess)
Private Declare Function GetModuleFileNameEx Lib "psapi.dll" Alias "GetModuleFileNameExA" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFilename As String, ByVal nSize As Long) As Long
'énumére les modules d'un processus
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef lpcbNeeded As Long) As Long

'renvoie le nom et le chemin du processus parent de "ProcessID"
'============================================
'ProcessID : ID du processus dont on veut connaitre le nom d'exe du parent (nom et chemin)
Public Function GetParentProcessName(ProcessID As Long) As String
Dim hToolHelp As Long       'handle de la vue des processus du système
Dim p As PROCESSENTRY32     'infos sur le processus "ProcessID"
Dim pp As PROCESSENTRY32    'infos sur le processus parent de "ProcessID"

'on demande une vue des processus du système
hToolHelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)

'on initialise la taille de la structure des infos
p.dwSize = Len(p)
'on demande les infos sur le premier processus de la vue
If Process32First(hToolHelp, p) Then
    'si ce n'est pas le processus recherché
    If p.th32ProcessID <> ProcessID Then
        'on réinitialise la taille de la structure des infos
        p.dwSize = Len(p)
        'tant qu'il y a des processus dans la vue
        Do While Process32Next(hToolHelp, p)
            'si le processus est celui recherché, on quitte la boucle
            If p.th32ProcessID = ProcessID Then Exit Do
            'sinon on réinitialise la taille de la structure des infos
            p.dwSize = Len(p)
        Loop
    End If
End If

'si NT, pour avoir le chemin complet de l'exe, il faut utiliser GetModuleFileNameEx avec l'id du processus parent
If IsWindowNT Then
    'on demande le chemin et le nom du processus
    GetParentProcessName = GetProcessFileName(p.th32ParentProcessID)
    'on ferme la vue
    CloseHandle hToolHelp
    'on renvoie le résultat
    Exit Function
Else
    'sinon, sous 9x/ME, szExeFile du processus parent contient le chemin et le nom complet de l'exe du processus
    'on cherche le processus parent dans la vue des processus
    
    'on initialise la taille de la structure des infos
    pp.dwSize = Len(pp)
    'on demande le premier processus de la vue
    If Process32First(hToolHelp, pp) Then
        'si ce n'est pas celui recherché
        If pp.th32ProcessID <> p.th32ParentProcessID Then
            'on réinitialise la taille de la structure des infos
            pp.dwSize = Len(pp)
            'tant qu'il y a encore des processus dans la vue
            Do While Process32Next(hToolHelp, pp)
                'si le processus est celui recherché, on quitte la boucle
                If pp.th32ProcessID = p.th32ParentProcessID Then Exit Do
                'sinon, on réinitialise la taille de la structure des infos
                pp.dwSize = Len(pp)
            Loop
        End If
    End If
End If

'on copie le nom complet de l'exe
GetParentProcessName = pp.szExeFile
'sans le vbNullChar de la fin de chaine
GetParentProcessName = Left$(GetParentProcessName, InStr(GetParentProcessName, vbNullChar) - 1)

'on ferme le handle de la vue
CloseHandle hToolHelp
End Function

'renvoie le chemin complet du processus ou FileName en cas d'erreur
'==================================================================
'PID : ID de processus dont on veut savoir le nom d'exe (nom et chemin)
'FileName : nom renvoyé si échec (par ex : CSRSS.exe (windows interdit son accès à des process ring3))
Public Function GetProcessFileName(PID As Long, Optional FileName As String) As String
    On Error GoTo Fin
    'si c le processus 0 (idle), windows ne lui donne pas de nom particulier
    If PID = 0 Then
        GetProcessFileName = "Idle"
    'si c le processus 4 (system), windows ne lui donne pas de nom particulier
    ElseIf PID = 4 Then
        GetProcessFileName = "System"
    Else
        'sinon, on demande son nom
        Dim hProcess As Long    'handle du processus
        Dim hModule As Long     'handle du module de l'exe
        Dim ret As Long         'résultat
        
        'on demande un handle pour le processus
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0&, PID)
        'si erreur : par exemple error_access_denied avec CSRSS.exe
        If hProcess = 0 Then GoTo Fin
        'on demande le handle du module de l'exe
        EnumProcessModules hProcess, hModule, 4&, ret
        'on alloue de la place pour son nom complet
        GetProcessFileName = Space(260)
        'on demande son nom complet
        GetModuleFileNameEx hProcess, hModule, GetProcessFileName, 260
        'on ferme le handle
        CloseHandle hProcess
        'on retire le vbNUllChar de fin de chaine
        GetProcessFileName = Left$(GetProcessFileName, InStr(GetProcessFileName, vbNullChar) - 1)
    End If
    
    Exit Function
Fin:
    'si erreur, on renvoie FileName
    GetProcessFileName = FileName
End Function

'renvoie le nom complet du processus parent du notre
Public Function GetCurrentProcessParent() As String
    GetCurrentProcessParent = GetParentProcessName(GetCurrentProcessId)
End Function

'indique si on execute ce code sous NT
Private Function IsWindowNT() As Boolean
    Dim os As OSVERSIONINFO
    
    'initialisation de la taille de la structure
    os.dwOSVersionInfoSize = Len(os)
    'demande de la version de windows
    GetVersionEx os
    'est-ce NT/2000/XP
    IsWindowNT = (os.dwPlatformId = VER_PLATFORM_WIN32_NT)
End Function

'renvoie la liste des processus
'==============================================
'Paths : indique si le chemin de l'exe doit être inclu (sous NT/2000/XP)
Public Function GetProcessesList(Optional Paths As Boolean = False) As PROCESSENTRY32()
Dim hToolHelp As Long       'handle de la vue des processus
Dim p As PROCESSENTRY32     'infos sur un processus
Dim t() As PROCESSENTRY32   'liste temporaire des processus
Dim cnt As Long             'compteur

'on demande une vue des processus du système
hToolHelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)

'compteur à 0
cnt = 0
'taille
p.dwSize = Len(p)
'on demande le premier processus de la vue
If Process32First(hToolHelp, p) Then
    'on alloue la place dans la liste temporaire
    ReDim t(0)
    'on copie les infos
    t(0) = p
    'taille
    p.dwSize = Len(p)
    'tant qu'il y a des processus dans la vue, on les ajoute à la liste temporaire
    Do While Process32Next(hToolHelp, p)
        cnt = cnt + 1
        ReDim Preserve t(cnt)
        'on supprime le vbNullChar et les espaces inutiles
        p.szExeFile = Left$(p.szExeFile, InStr(p.szExeFile, vbNullChar) - 1)
        'on copie les infos
        t(cnt) = p
        'si c windows et que l'on veut les chemins complets
        If (IsWindowNT = True) And (Paths = True) Then t(cnt).szExeFile = GetProcessFileName(p.th32ProcessID, t(cnt).szExeFile)
        'taille
        p.dwSize = Len(p)
    Loop
End If

Dim x As Long, y As Long        'compteur
Dim temp As PROCESSENTRY32      'valeur temporaire

'on trie le tableau pour mettre les parents avant les enfants
'pourchaque enfant
For x = 0 To UBound(t)
    'on regarde si le parent est après
    For y = x + 1 To UBound(t)
        'si oui, on inverse parent et enfant
        If (t(x).th32ParentProcessID = t(y).th32ProcessID) Then
            'stockage temporaire
            temp = t(y)
            'inversement
            t(y) = t(x)
            t(x) = temp
        End If
    Next
Next

'on renvoie la liste
GetProcessesList = t
'on ferme la vue
CloseHandle hToolHelp
End Function

Conclusion :


Ce code suit une question du forum...

N'hésitez pas à commenter et à noter...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.