73 votes

Comment obtenir le handle d'un processus par son nom en C++ ?

J'essaie d'obtenir le gestionnaire de processus de, disons exemple.exe, afin que je puisse appeler TerminateProcess sur elle. Comment puis-je faire ça ? Remarquez qu'il n'y a pas de fenêtre, donc FindWindow ne fonctionnera pas.

97voto

xian Points 2714
#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>

int main( int, char *[] )
{
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE)
    {
        while (Process32Next(snapshot, &entry) == TRUE)
        {
            if (stricmp(entry.szExeFile, "target.exe") == 0)
            {  
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);

                // Do stuff..

                CloseHandle(hProcess);
            }
        }
    }

    CloseHandle(snapshot);

    return 0;
}

Par ailleurs, si vous souhaitez utiliser PROCESS_ALL_ACCESS dans OpenProcess, vous pouvez essayer ceci :

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

void EnableDebugPriv()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);

    CloseHandle(hToken); 
}

int main( int, char *[] )
{
    EnableDebugPriv();

    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE)
    {
        while (Process32Next(snapshot, &entry) == TRUE)
        {
            if (stricmp(entry.szExeFile, "target.exe") == 0)
            {  
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);

                // Do stuff..

                CloseHandle(hProcess);
            }
        }
    }

    CloseHandle(snapshot);

    return 0;
}

11 votes

Votre code sautera le premier processus dans le système (cependant, le premier processus est très probablement "SYSTEM" donc pas de bug visible par l'utilisateur).

0 votes

Le premier processus est SYSTEM, donc c'est bon (j'ai littéralement pris ce code directement d'un de mes projets) ;)

0 votes

Lorsque je tente d'agir sur le hProcess, j'obtiens le code d'erreur 6, qui est ERROR_INVALID_HANDLE.

18voto

Michael Points 34110

Le code suivant montre comment vous pouvez utiliser toolhelp et OpenProcess pour obtenir un handle sur le processus. La gestion des erreurs a été supprimée pour des raisons de concision.

HANDLE GetProcessByName(PCWSTR name)
{
    DWORD pid = 0;

    // Create toolhelp snapshot.
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);

    // Walkthrough all processes.
    if (Process32First(snapshot, &process))
    {
        do
        {
            // Compare process.szExeFile based on format of name, i.e., trim file path
            // trim .exe if necessary, etc.
            if (MatchProcessName(process.szExeFile, name)
            {
               pid = process.th32ProcessID;
               break;
            }
        } while Process32Next(snapshot, &process);
    }

    CloseHandle(snapshot);

    if (pid != 0)
    {
         return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    }

    // Not found

       return NULL;
}

0 votes

Vous avez oublié une parenthèse dans la condition "if (MatchProcessName(process.szExeFile, name)".

0 votes

Comme la réponse de xian, ceci a une condition de course et est intrinsèquement dangereux.

0 votes

@Occulta if (string(process.szExeFile) == string(name)) peut être utilisé à la place de cette fonction. J'ai édité la réponse de Michael.

17voto

Rob Kennedy Points 107381

Il existe deux techniques de base. La première utilise PSAPI ; MSDN dispose de un exemple qui utilise EnumProcesses , OpenProcess , EnumProcessModules et GetModuleBaseName .

L'autre utilise Toolhelp, que je préfère. Utiliser CreateToolhelp32Snapshot pour obtenir un instantané de la liste des processus, parcourez-la avec Process32First et Process32Next qui fournit le nom du module et l'ID du processus, jusqu'à ce que vous trouviez celui que vous voulez, et ensuite appelez OpenProcess pour avoir une idée.

2voto

Lloyd Points 16334

Vérifiez : Article de MSDN

Vous pouvez utiliser GetModuleName (je crois ?) pour obtenir le nom et le vérifier.

0 votes

La plupart des noms GetModuleName, QueryFullProcessImage, etc., nécessitent un handle et ne seront donc pas d'une grande utilité. Toolhelp renvoie le nom du processus.

1voto

Windows dispose de plusieurs API pour l'énumération des processus - voir http://msdn.microsoft.com/en-us/library/ms684865%28VS.85%29.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X