プロセスイメージ名を介してプロセスを終了するための単純な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>
不足している。