c - Hvad er Windows tilsvarende 'pidof' fra Linux?

Indlæg af Hanne Mølgaard Plasc

Problem



I et batchcript skal jeg få en liste over proces-id'er med en given binær sti C:path oinary.exe.
I Linux kan jeg bare gøre pidof /path/to/binary.


Er der en Win32 eksekverbar, som gør det samme, understøttet fra WinXP Home til Win7 (opgaveliste vandt? T arbejde)?


Pakken, som indeholder dette, skal være bærbar, så en download på 10 MB er ikke det, jeg leder efter.


Er der en C-funktion tilgængelig, som understøttes af denne og fra WinXP til Win7? Bemærk: Jeg vil matche en processti, ikke et filnavn, som også kunne bruges af andre applikationer.

Bedste reference


Du kan bruge API'er til værktøjshjælp til at optælle processer, få deres fulde sti og sammenligne den med det krævede procesnavn. Du skal gå til modullisten for hver proces. Det første modul i listen er selve processen, der kan køre. Her er en prøvekode:



int main( int argc, char* argv[] )
{

    if( argc > 1 )
    {
        printf( "
Getting PID of: \%s
", argv[1] );
        HANDLE hProcSnapshot = ::CreateToolhelp32Snapshot( TH32CS\_SNAPPROCESS, 0 );
        if( INVALID\_HANDLE\_VALUE != hProcSnapshot )
        {
            PROCESSENTRY32 procEntry = {0};
            procEntry.dwSize = sizeof(PROCESSENTRY32);
            if( ::Process32First( hProcSnapshot, &procEntry ) )
            {
                do
                {
                    HANDLE hModSnapshot = ::CreateToolhelp32Snapshot( TH32CS\_SNAPMODULE, procEntry.th32ProcessID );
                    if( INVALID\_HANDLE\_VALUE != hModSnapshot )
                    {
                        MODULEENTRY32 modEntry = {0};
                        modEntry.dwSize = sizeof( MODULEENTRY32 );
                        if( Module32First( hModSnapshot, &modEntry ) )
                        {
                            if( 0 == stricmp( argv[1], modEntry.szExePath ) )
                            {
                                printf( "
PID: \%ld
", procEntry.th32ProcessID );
                                ::CloseHandle( hModSnapshot );
                                break;
                            }
                        }
                        ::CloseHandle( hModSnapshot );
                    }
                }
                while( ::Process32Next( hProcSnapshot, &procEntry ) );
            }
            ::CloseHandle( hProcSnapshot );
        }
    }
    return 0;
}

Andre referencer 1


wmic.exe er tilgængelig på XP, Vista og 7 og kan gøre dette. Men det kommer ikke med Windows XP Home Edition.


wmic process where ExecutablePath='C:\windows\system32\notepad.exe' get ProcessId


Hvis du også vil have support til Windows XP Home, kan du også bruge EnumProcess og GetModuleFileNameEx. Ulempen her er, at du ikke kan forespørge navne på processer, der kører af en anden bruger, hvis du ikke kører som administrator. QueryFullProcessImageName vil nok gøre det her, men det er Vista +. [7] [8] [9]


Hvis det ikke er nok, skal du have Process32First (swatkat's kode). For hver proces skal du ringe Module32First og derefter få MODULEENTRY32->szExePath. Bemærk at selv dette ikke er helt bærbart og fungerer ikke godt x64 hvor du skal bruge QueryFullProcessImageName. [10] [11] [12]

Andre referencer 2


Du kan skrive en lille C # -applikation, som først kalder Process.GetProcessesByName (String), derefter gå over resultaterne og udskrive ID-egenskaben for hver enkelt, når MainModule.FileName er lig med den sti, du leder efter. [13] [14] [15]

Andre referencer 3


PowerShell kan løse dine problemer, hvis det er buit i Win 7 og downloades på de andre OS'er.


param($fileName)
Get-Process | where -FilterScript {$\_.MainModule.FileName -eq $fileName}


Dette script vil modtage en parameter, filnavnet du leder efter, og det vil udgive filnavnet til dets eksekverbare.


Du kan kalde dette fra en flagermusfil ved at gøre:


powershell -Command '&{Get-Process | hvor -FilterScript {$ \_. MainModule.FileName -eq\% FILENAME\%}'