Идентификаторы процессов и имена процессов - PullRequest
1 голос
/ 02 мая 2011

Я создаю программу для Windows, которая в основном сканирует систему, чтобы увидеть, запущен определенный процесс или нет.У меня есть имя процесса (AcroRd32.exe) и ничего больше.

Из того, что я прочитал, самый простой способ создать снимок всех процессов, используя CreateToolhelp32Snapshot , а затем выполнить итерацию по каждому процессуищу имя процесса.

Мое приложение ориентировано на высокую производительность.Так есть ли лучший, более эффективный способ сделать это.Приложение собирает снимок каждые несколько секунд.Повторение сотен процессов в снимке не кажется эффективным.Есть ли прямой API, который может найти Процесс по имени процесса (и получить дескриптор или идентификатор процесса по имени)?

Я много раз искал без особой удачи.Кто-нибудь пробовал это раньше?

Ответы [ 2 ]

4 голосов
/ 03 мая 2011

Самый быстрый способ поиска процессов - это вызов NTDLL NtQuerySystemInformation.Он предоставляет вам список имен и идентификаторов процессов всех процессов в системе за один вызов (или более в редких случаях, например, при большом количестве процессов).Вы можете комбинировать NtQuerySystemInformation и использовать хеш для сравнения строк вместо сравнения каждого байта.

// headers @ http://pastebin.com/HWzJYpbv


NtQuerySystemInformation = (_RT_NAPI_QUERYSYSINFO)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQuerySystemInformation");

    // Get process information buffer
    do {
        // Allocate buffer for process info
        pBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBuffer); 
        if (pBuffer == NULL) {
            // Cannot allocate enough memory for buffer (CRITICAL ERROR)
            return 1;
        }

        // Obtain system process snapshot
        Status = NtQuerySystemInformation(5, pBuffer, cbBuffer, NULL);

        // Allocate bigger buffer for moar data
        if (Status == STATUS_INFO_LENGTH_MISMATCH) {
            HeapFree(hHeap, 0, pBuffer);
            cbBuffer *= 2; // Increase the size of the buffer :-)
        } else if ((Status) != 0x00) {
            // Can't query process information (probably rootkit or anti-virus)
            HeapFree(hHeap, 0, pBuffer);
            return 1;
        }
    } while (Status == STATUS_INFO_LENGTH_MISMATCH);

    // Get pointer to first system process info structure
    pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;

    // Loop over each process
    for (;;) {
        // Get process name
        pszProcessName = pInfo->ImageName.Buffer;

        // ... do work. For a fast string compare, calculate a 32-bit hash of the string, then compare to a static hash.
        if(CRC32(pszProcessName) == 0xDEADBEEF /* <- hash of adobe reader process name goez here */) {
            // Found process
        }

        // Load next entry
        if (pInfo->NextEntryOffset == 0)
            break;
        pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+ pInfo->NextEntryOffset);
    }

Протестировано в Windows 2000 - английские издания Windows 7, x64 / x86 (кроме Win XP x64) Примечание. Он вернет все процессы 32-разрядным процессам WOW64 в 64-разрядных системах.

3 голосов
/ 02 мая 2011

номер

Каждый процесс имеет уникальный идентификатор , но не уникальное имя . Может быть несколько процессов с одним и тем же именем. Поэтому невозможно получить дескриптор процесса из его имени напрямую, не повторяя все процессы.

Внутренне все процессы каким-то образом связаны друг с другом, например, в связанном списке. Даже если бы была предусмотрена функция GetProcessByName(), она бы внутренне прошла через список, чтобы найти процессы с таким именем и от вашего имени. Так что это не будет иметь большого значения в производительности.

Помимо

Дайте выстрел в EnumProcesses(), который имеет меньше накладных расходов и проще. Отметьте здесь .

BOOL WINAPI EnumProcesses(
  __out  DWORD *pProcessIds,
  __in   DWORD cb,
  __out  DWORD *pBytesReturned
);

MSDN имеет пример для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...