Простая программа C WinAPI для завершения процессов с помощью имен образов процессов

Aug 20 2020

(Также см. Следующую итерацию .)

У меня есть эта небольшая программа для завершения процессов через соответствующие им имена ( .exeфайлы) образов процессов :

#include <stdio.h>
#include <windows.h>
#include <TlHelp32.h>

int main(int argc, char* argv[]) {
    if (argc != 2) {
        puts("processkiller.exe PROCESS_NAME");
        return EXIT_SUCCESS;
    }

    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE) {
        while (Process32Next(snapshot, &entry) == TRUE) {
            if (strcmp(entry.szExeFile, argv[1]) == 0) {
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 
                                              FALSE, 
                                              entry.th32ProcessID);
                TerminateProcess(hProcess, 0);
                CloseHandle(hProcess);
            }
        }
    }

    CloseHandle(snapshot);
    return EXIT_SUCCESS;
}

Обратите внимание, что вам нужно запустить processkiller.exeв режиме администратора, чтобы фактически завершить запрошенные процессы.

Запрос на критику

Пожалуйста, расскажите мне все, что придет в голову.

Ответы

4 MartinR Aug 20 2020 at 19:37

Есть небольшая ошибка:

Process32First(snapshot, &entry)

уже заполняет entryинформацию о первом процессе в снимке. Ваш код пропускает эту запись, потому что Process32Next()вызывается немедленно. Структура петли должна быть

if (Process32First(snapshot, &entry) == TRUE) {
    do {
        // ... do something with `entry`...
        
    } while (Process32Next(snapshot, &entry) == TRUE);
}

вместо. Другие вещи, которые приходят мне в голову:

  • Если программа вызывается с неправильным числом аргументов, то сообщение об ошибке / использовании должно быть напечатано до стандартной ошибки, и программа должна завершиться с ненулевым кодом выхода, например EXIT_FAILURE.
  • Возвращаемое значение CreateToolhelp32Snapshot()не проверяется.
  • PROCESS_ALL_ACCESSне требуется в вызове OpenProcess, только PROCESS_TERMINATE.
  • Возвращаемые значения OpenProcess()и TerminateProcess()не проверяются. Я бы ожидал диагностического сообщения, если они не работают. В частности, TerminateProcess()и CloseHandle()должен вызываться только в случае OpenProcess()успеха.
  • Это может быть дело вкуса, но == TRUEего можно опустить при проверке логического условия.
  • Как пользователь этого инструмента я ожидаю некоторой обратной связи, чтобы увидеть, был ли найден соответствующий процесс и сколько процессов было убито.