FAQ Win32Consultez toutes les FAQ

Nombre d'auteurs : 11, nombre de questions : 72, dernière mise à jour : 2 septembre 2018 

 
OuvrirSommaireProcessus et threads

L'API CreateProcess permet de créer un nouveau processus en spécifiant le nom ou le chemin de l'exécutable à lancer.

 
Sélectionnez
#include <windows.h>
 
int main()
{
    STARTUPINFO si;         /* Requis par CreateProcess */
    PROCESS_INFORMATION pi; /* Requis par CreateProcess */
 
    /* La structure si est utilisée en entrée donc elle doit être mpérativement initialisée    */
    ZeroMemory(&si, sizeof(si));
 
    /* Pas la peine d'initialiser la structure pi car elle sera écrite et non lue              */
 
    if (CreateProcess( "c:\\developpez\\test.exe",       /* Nom de l'exécutable                    */
                       NULL,      /* Arguments de la ligne de commande                             */
                       NULL,      /* Attributs de sécurité du nouveau processus (processus fils)   */
                       NULL,      /* Attributs de sécurité du thread principal                     */
                       FALSE,     /* Le processus fils héritera t-il des handles du processus père */
                       0,         /* Flags de création                                             */
                       NULL,      /* Variables d'environnement                                     */
                       NULL,      /* Répertoire courant                                            */
                       &si,       /* Paramètres d'initialisation du processus                      */
                       &pi        /* Informations sur le processus                                 */ ))
    {
        WaitForSingleObject(pi.hProcess, INFINITE);      /* Attendre la fin du processus           */
 
        CloseHandle(pi.hProcess); /* Fermer le handle vers le processus                            */
        CloseHandle(pi.hThread);  /* Fermer le handle vers le thread principal du processus        */
    }
 
    return 0;
}


L'API ShellExecute permet d'ouvrir un fichier (pas nécessairement un exe) ou un dossier exactement comme si on avait double-cliqué sur ce fichier ou dossier depuis l'explorateur. D'autres actions, par exemple imprimer (si le document est imprimable), sont également possibles.

 
Sélectionnez
#include <windows.h>
 
int main()
{
    ShellExecute( NULL,                       /* Fenêtre parent                    */
                  "open",                     /* Action à faire                    */
                  "c:\\developpez\\test.exe", /* Nom du fichier                    */
                  NULL,                       /* Arguments de la ligne de commande */
                  NULL,                       /* Répertoire courant                */
                  SW_SHOWNORMAL               /* Comment afficher la fenêtre       */ );
 
    return 0;
}


ShellExecute exécute l'opération demandée et retourne immédiatement. Pour plus de contrôle, utilisez ShellExecuteEx.

Créé le 28 juillet 2008  par Melem

Le plus simple est d'utiliser CreateProcessWithLogonW qui s'utilise comme CreateProcess sauf qu'il faut également spécifier le nom et le mot de passe de l'utilisateur qui désire créer le processus. Si elle est susceptible d'être appelée assez souvent dans le programme, alors il sera peut-être interessant de créer un handle vers un objet qui représente un utilisateur en utilisant la fonction LogonUser et d'appeler ensuite CreateProcessAsUser en fournissant ce handle chaque fois qu'on veut lancer un programme avec les droits de cet utilisateur. Il ne faut pas oublier de fermer le handle (CloseHandle) avant de quitter le programme.

Créé le 28 juillet 2008  par Melem

Cela n'est pas possible car plusieurs instances de l'application peuvent exister en mémoire au même moment. La seule information qui permet d'identifier un processus est le PID (Process ID), qui est un numéro unique attribué par Windows à chaque processus créé.

Créé le 28 juillet 2008  par Melem

A l'aide de la fonction OpenProcess. Toujours fermer le handle à l'aide de la fonction CloseHandle lorsqu'on en a plus besoin.

Créé le 28 juillet 2008  par Melem

Pour faire certaines opérations, par exemple lire ou écrire dans la mémoire d'un autre processus, il faut avoir certains privilèges. La fonction AdjustTokenPrivileges premet d'ajuster les privilèges d'un processus. Voici un exemple (éteindre l'ordinateur) :

 
Sélectionnez
#include <windows.h>
 
void PowerOff()
{
    HANDLE hToken;                     /* Handle vers les privilèges du processus                     */
    TOKEN_PRIVILEGES token_privileges; /* Structure permettant de représenter un groupe de privilèges */
    LUID luid;                         /* Locally Unique ID (ID Local d'un privilège)                 */
 
    /* Il faut obtenir un handle vers les privilèges du processus qui nous intéresse.                 */
 
    OpenProcessToken( NULL,             /* Handle du processus                                        */
                      TOKEN_ALL_ACCESS, /* Ce que nous souhaitons faire avec le Token Handle          */
                      &hToken           /* Sortie                                                     */ );
 
    /* SE_SHUTDOWN_NAME ("SeShutdownPrivilege") est requis pour pouvoir éteindre l'ordinateur.        */
    /* Récupérons le LUID de ce privilège.                                                            */
 
    LookupPrivilegeValue( NULL,             /* Sur quelle machine ?                                   */
                          SE_SHUTDOWN_NAME, /* Nom du privilège dont le LUID nous intéresse           */
                          &luid             /* Sortie                                                 */ );
 
    /* Composons les nouveaux privilèges du processus.                                                */
 
    token_privileges.PrivilegeCount = 1;
 
    token_privileges.Privileges[0].Luid       = luid;
    token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
    /* Appliquons.                                                                                    */
 
    AdjustTokenPrivileges( hToken,            /* Token Handle                                         */
                           FALSE,             /* Désactiver tous les privilèges ? (DAP)               */
                           &token_privileges, /* Nouvel état (ignoré si DAP vaut TRUE)                */
                           0,                 /* sizeof(old_state)                                    */
                           NULL,              /* &old_state                                           */
                           NULL               /* &retun_length                                        */ );
 
    /* C'est fait. Fermons le Token Handle.                                                           */
 
    CloseHandle(hToken);
 
    /* On peut maintenant éteindre l'ordinateur.                                                      */
 
    ExitWindowsEx(EWX_POWEROFF, 0);
}
Créé le 28 juillet 2008  par Melem

Il existe actuellement deux APIs permettant de lister, entre autres, tous les processus en cours. La première est la Toolhelp API que les développeurs de Windows 9x/Me ont ajouté en "complément" à l'API Win32. La deuxième est la PSAPI (Process Status helper API) qui est la réponse (tardive) des développeurs de WINNT à la Toolhelp API. Cette API, implémentée par le fichier (redistribuable) psapi.dll, est incluse dans Windows 2000 et plus récents. En addition, la Toolhelp API a également été ajoutée à ces systèmes.

Voici un programme qui affiche la liste de tous les processus en cours en utilisant la Toolhelp API :

 
Sélectionnez
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
 
int main()
{
    HANDLE hSnapShot;
    PROCESSENTRY32 pe;
 
    /* Demander une vue de tous les processus en cours */
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
    /* Afficher les résultats                          */
    if (Process32First(hSnapShot, &pe))
    {
        do
            printf("%-20s (pid = %4lu)\n", pe.szExeFile, pe.th32ProcessID);
        while (Process32Next(hSnapShot, &pe));
    }
 
    CloseHandle(hSnapShot);
 
    return 0;
}


Avec la PSAPI, on appelle EnumProcesses pour avoir les PIDs des différents processus en cours, esnuite OpenProcess sur chaque PID pour avoir un handle vers ce processus et enfin GetModuleBaseName ou GetModuleFileNameEx pour avoir le nom du processus (nom seulement avec la première et le chemin complet avec la seconde). Inclure psapi.h et ajouter psapi.lib dans les entrées du linkeur.

Créé le 28 juillet 2008  par Melem

Toujours faisable avec la Toolhelp API ou la PSAPI. Le programme suivant utilise la Toolhelp API pour lister tous les modules chargés par lui-même.

 
Sélectionnez
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
 
int main()
{
    HANDLE hSnapShot;
    MODULEENTRY32 me;
 
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
 
    me.dwSize = sizeof(me); /* Il faut initialiser ce champ avant d'appeler Module32First. */
 
    if (Module32First(hSnapShot, &me))
    {
        do
            printf("%s\n", me.szModule);
        while (Module32Next(hSnapShot, &me));
    }
 
    CloseHandle(hSnapShot);
 
    return 0;
}
 

Remplacez me.szModule par me.szExePath pour avoir le chemin complet du module au lieu de son nom uniquement.

Avec la PSAPI, on appelle EnumProcessModules suivi de GetModuleBaseName ou GetModuleFileNameEx sur chaque module.

Créé le 28 juillet 2008  par Melem

Rien de spécial. Fermer un handle vers un processus ou un thread ne le tue pas mais libère tout simplement le handle. Pour terminer un processus (respectivemet un thread), il faut appeler TerminateProcess (respectivement TerminateThread).

Créé le 28 juillet 2008  par Melem

A l'aide de la fonction GetWindowThreadProcessId.

Créé le 28 juillet 2008  par Melem

La fonction GetModuleFileName permet de connaître le chemin complet du processus courant. Pour obtenir le chemin complet d'un autre processus, on pourra utiliser la fonction GetModuleFileNameEx de la PSAPI. Il n'y a pas d'équivalent direct de cette fonction dans la Toolhelp API donc, avec cette API, on est obligé d'énumérer les modules chargés par le processus jusqu'à trouver l'exe lui-même.

Créé le 28 juillet 2008  par Melem

SetCurrentDirectory(<nouveau répertoire courant>).

Créé le 28 juillet 2008  par Melem
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 Developpez.com Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.