プロセスイメージ名を介してプロセスを終了するための単純なCWinAPIプログラム-フォローアップ

Aug 22 2020

(このツールの以前の(つまり最初の)バージョンを参照してください。)

(次のフォローアップを参照してください。)

Martin Rによるすべてのアドバイスを考慮した後、指定されたプロセスイメージ名ですべてのプロセスを終了するための次のツールに行き着きました。

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

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

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

    if (snapshot == INVALID_HANDLE_VALUE) {
        fputs("Error: could not get the process snapshot.", stderr);
        return EXIT_FAILURE;
    }

    size_t totalProcessesMatched = 0;
    size_t totalProcessesTerminated = 0;

    if (Process32First(snapshot, &entry)) {
        do {
            if (strcmp(entry.szExeFile, argv[1]) == 0) {
                totalProcessesMatched++;

                HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 
                                              FALSE, 
                                              entry.th32ProcessID);

                if (hProcess == NULL) {
                    fprintf(stderr,
                            "Error: could not open the process with ID = %d, "
                            "called \"%s\".\n", 
                            entry.th32ProcessID, 
                            entry.szExeFile);
                } else {
                    BOOL terminated = TerminateProcess(hProcess, 0);

                    if (terminated) {
                        totalProcessesTerminated++;

                        BOOL closed = CloseHandle(hProcess);

                        if (!closed) {
                            fprintf(stderr,
                                    "Warning: could not close a handle "
                                    "for process ID = %d, called \"%s\".\n",
                                    entry.th32ProcessID, 
                                    entry.szExeFile);
                        }

                        printf("Terminated process ID %d\n", entry.th32ProcessID);
                    }
                }
            }
        } while (Process32Next(snapshot, &entry));
    }

    BOOL snapshotHandleClosed = CloseHandle(snapshot);

    if (!snapshotHandleClosed) {
        fputs("Warning: could not close the process snapshot.", stderr);
    }

    printf("Info: total matching processes: %d, total terminated: %d.\n", 
           totalProcessesMatched, 
           totalProcessesTerminated);

    return EXIT_SUCCESS;
}

批評依頼

私はどこかに行きますか?このツールは正しくコーディングされていますか?統計/エラー情報について十分に冗長ですか?

回答

2 user3629249 Aug 22 2020 at 21:33

について:

size_t totalProcessesMatched = 0;
size_t totalProcessesTerminated = 0;
...
printf("Info: total matching processes: %d, total terminated: %d.\n", 
       totalProcessesMatched, 
       totalProcessesTerminated);

printf()出力aにしようとしているintが、出力に変数があるsize_t使用して出力であるべき%zu書式指定子を。

コンパイラがこれらの種類の問題について通知していない場合は、通知が表示されるまで警告を有効にしてください。

に関して;

fprintf(stderr, "processkiller.exe PROCESS_NAME");  

これは、1)stderrフォーマット文字列\nの末尾にがないため、出力ストリームに残ります。2)任意のプログラムは任意の名前で実行できるため、名前をハードコーディングすることはお勧めできません。提案:

fprintf(stderr, "%s PROCESS_NAME\n", argv[0] );

に関して:

fputs("Error: could not get the process snapshot.", stderr);

このget_last_error()機能を利用して、stderr「ランダムな」エラーメッセージではなく、実際のエラーテキストを印刷することを強くお勧めします。

に関して;

if (strcmp(entry.szExeFile, argv[1]) == 0) {

次の理由により、これはコンパイルされません。

#include <string.h>

不足している。