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

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ませんが、ブール状態をチェックするときは省略できます。
  • このツールのユーザーとして、一致するプロセスが見つかったかどうか、および強制終了されたプロセスの数を確認するためのフィードバックを期待します。