Un programa simple de C WinAPI para terminar procesos mediante nombres de imagen de proceso

Aug 20 2020

(Además, vea la siguiente iteración ).

Tengo este pequeño programa para terminar procesos a través de sus respectivos nombres de imagen de proceso ( .exearchivos):

#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;
}

Tenga en cuenta que debe ejecutar processkiller.exeen modo administrador para finalizar los procesos solicitados.

Solicitud de crítica

Por favor, dígame todo lo que se le ocurra.

Respuestas

4 MartinR Aug 20 2020 at 19:37

Hay un error sutil:

Process32First(snapshot, &entry)

ya se llena entrycon la información sobre el primer proceso en la instantánea. Su código pierde esa entrada porque Process32Next()se llama inmediatamente. La estructura del bucle debe ser

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

en lugar. Otras cosas que me vienen a la mente:

  • Si se llama al programa con un número incorrecto de argumentos, entonces el mensaje de error / uso debe imprimirse en el error estándar y el programa debe terminar con un código de salida distinto de cero , por ejemplo EXIT_FAILURE.
  • CreateToolhelp32Snapshot()No se comprueba el valor de retorno de .
  • PROCESS_ALL_ACCESSno es necesario en la llamada a OpenProcess, solo PROCESS_TERMINATE.
  • Los valores devueltos de OpenProcess()y TerminateProcess()no se comprueban. Esperaría un mensaje de diagnóstico si fallan. En particular, TerminateProcess()y CloseHandle()solo se debe llamar si se realiza OpenProcess()correctamente.
  • Puede ser una cuestión de gustos, pero == TRUEse puede omitir al verificar una condición booleana.
  • Como usuario de esta herramienta, esperaría recibir comentarios para ver si se encontró un proceso coincidente y cuántos procesos se eliminaron.