AJINKYA
AJINKYA

Reputation: 811

get a process id from process name

Hi i am trying to do a project using windows API in C language. The small part in my project is to get process ID of lsass.exe.

i have tried the program below but it wont work. i have read about the CreateToolhelp32Snapshot, Process32First, Process32Next functions can anyone help me explaining how to use them in the code.

So please help me. i am a beginner to windows API so i will appreciate it if anyone can suggest me an good ebook to refer.

Upvotes: 5

Views: 13743

Answers (4)

user2173353
user2173353

Reputation: 4660

This is modification of Luis G. Costantini R. code.

It uses MFC:

#include "TlHelp32.h"

BOOL GetProcessList(const TCHAR *processname, CArray<DWORD> &PIDs)
{
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // Take a snapshot of all processes in the system.
    HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hProcessSnap) return FALSE;

    // Retrieve information about the first process,
    // and exit if unsuccessful
    if (!::Process32First(hProcessSnap, &pe32))
    {
        CloseHandle(hProcessSnap);          // clean the snapshot object
        return FALSE;
    }

    do
    {
        if (0 == _tcsicmp(processname, pe32.szExeFile))
        {
            PIDs.Add(pe32.th32ProcessID);
        }
    }
    while (::Process32Next(hProcessSnap, &pe32));

    ::CloseHandle(hProcessSnap);
    return TRUE;
}

Upvotes: 1

Luis G. Costantini R.
Luis G. Costantini R.

Reputation: 1128

There is an example of how to use CreateToolhelp32Snapshot, Process32First, Process32Next (You have to add error handles, etc. and include tlhelp32.h in your code). By the way this functions are not compatible with Windows NT:

BOOL GetProcessList(const char *processname, DWORD **processIds, int *numprocess)
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    DWORD *processIdsTmp;

    *processIds = NULL;
    *numprocess = 0;
    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( INVALID_HANDLE_VALUE == hProcessSnap ) return( FALSE );

    // Retrieve information about the first process,
    // and exit if unsuccessful
    if( !Process32First( hProcessSnap, &pe32 ) )
    {
        CloseHandle( hProcessSnap );          // clean the snapshot object
        return( FALSE );
    }

    do
    {
        if (0 == strcasecmp(processname, pe32.szExeFile))
        {
            processIdsTmp = realloc(*processIds, sizeof(DWORD) * ((*numprocess) + 1));
            if (NULL == processIdsTmp)
            {
                free(*processIds);
                *processIds = NULL;
                *numprocess = 0;
                CloseHandle( hProcessSnap );          // clean the snapshot object
                return( FALSE );
            }
            *processIds = processIdsTmp;
            (*processIds)[(*numprocess)++] = pe32.th32ProcessID;
        }
    } while( Process32Next( hProcessSnap, &pe32 ) );

    CloseHandle( hProcessSnap );
    return( TRUE );     
}

here is a complete example of the use of this funcions.

Upvotes: 0

Bob Moore
Bob Moore

Reputation: 6894

Because there might be several instances of a process name running, there is no one-to-one correlation between a process's image name and a PID. You'll have to enumerate the processes and check the base module names for each one as Burgos describes, by using EnumProcesses.

FWIW, .Net approaches this problem by providing the GetProcessesByName API, which returns a collection of process objects. Not much use to you of course :-(

Upvotes: 5

Nemanja Boric
Nemanja Boric

Reputation: 22187

I don't know for simplier way. This is working by finding every running PID and comparing its name to "lsass.exe".

    // pid.cpp : Defines the entry point for the console application.

    #include "stdafx.h"
    #include <windows.h>
    #include <psapi.h>

    int PrintProcessNameAndID( DWORD processID, const char *name )
    {
        TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

        // Get a handle to the process.

        HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                               PROCESS_VM_READ,
                               FALSE, processID );

        // Get the process name.

        if (NULL != hProcess )
        {
            HMODULE hMod;
            DWORD cbNeeded;

            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
                 &cbNeeded) )
            {
                GetModuleBaseName( hProcess, hMod, szProcessName, 
                                   sizeof(szProcessName)/sizeof(TCHAR) );
            }
        }


        if(strcmp(szProcessName, name) == 0) // right process
        {
                    CloseHandle(hProcess);
            return 1;
        }

        // Release the handle to the process.

        CloseHandle( hProcess );
        return 0;
     }

    int find(const char *name)
    {
    // Get the list of process identifiers.

        DWORD aProcesses[1024], cbNeeded, cProcesses;
        unsigned int i;

        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        {
            return 1;
        }


        // Calculate how many process identifiers were returned.

        cProcesses = cbNeeded / sizeof(DWORD);

        // Print the name and process identifier for each process.

        for ( i = 0; i < cProcesses; i++ )
        {
            if( aProcesses[i] != 0 )
            {
                if(PrintProcessNameAndID( aProcesses[i], name ))
                {
                    //found it
                    _tprintf("%d %s\n", aProcesses[i], name);
                }
               }
        }
 }

    int _tmain(int argc, _TCHAR* argv[])
    {
        find("lsass.exe");
        return 0;
    }

Upvotes: 2

Related Questions