Поскольку PROCESS_INFORMATION pif
содержит идентификатор недавно созданного процесса в DWORD dwProcessId
, вы можете, например, создать свой собственный список, добавив каждый pif.dwProcessId
к std::vector<DWORD> processIds
.
А чтобы завершить созданные процессы, просто сделайте что-то вроде
for (auto processId : processIds) {
TerminateMyProcess(processId, 1);
}
Edit:
Я думаю, что только что реализовал улучшение, используя std::remove_if
из #include <algorithm>
и std::bind
из #include <functional>
.
Вместо for(auto processId : processIds){...}
используйте это:
processIds.erase(std::remove_if(processIds.begin(), processIds.end(), std::bind(TerminateMyProcess, std::placeholders::_1, 1)));
С помощью std::remove_if
вы можете удалить элементы из контейнера, если переданная функция (в данном случае TerminateMyProcess
), которая принимает в качестве одного аргумента элемент из контейнера, возвращает true.
Поскольку TerminateMyProcess
, очевидно, имеет два аргумента, DWORD
и UINT
, мы можем использовать std :: bind в качестве функции-оболочки вокруг TerminateMyProcess
, которая принимает один аргумент DWORD
(placeholder :: _ 1), в то время как UINT
установлено на 1
.
Таким образом, успешно завершенные идентификаторы процессов будут удалены из вектора, оставив только идентификаторы процессов, которые не могут быть завершены.
Еще одно редактирование для отражения Комментарий IInspctable :
После того, как ваше приложение создало все эти процессы (в вашем примере notepad.exe), у каждого из них есть определенный идентификатор процесса. Представьте, например, что пока ваше приложение ожидает время завершения этих процессов, один из них уже завершается. Идентификатор процесса больше не используется и может быть назначен операционной системой новому и совершенно другому процессу, который не имеет никакого отношения к вашему приложению или notepad.exe. Обычно вы не хотите завершать какой-либо процесс. ;)
Создать один std::vector<HANDLE> processes
.
Для каждого созданного процесса сохраняйте pif.hProcess
в этом векторе. Не закрывайте ручку на этом этапе.
Измените TerminateMyProcess
на то, что он принимает HANDLE
в качестве первого аргумента.
Используйте
processes.erase(std::remove_if(processes.begin(), processes.end(), std::bind(TerminateMyProcess, std::placeholders::_1, 1)));
для завершения процессов и (в случае успешного завершения) удаления их дескрипторов из вектора. Оставшиеся дескрипторы можно использовать для обработки ошибок и т. Д.
Рабочий пример:
#include <Windows.h>
#include <process.h>
#include <vector>
#include <algorithm>
#include <functional>
#include <chrono>
#include <thread>
std::vector<HANDLE> processes;
void create_process() {
STARTUPINFO si;
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi;
SecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
if (CreateProcess(L"C:\\windows\\system32\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hThread);
processes.push_back(pi.hProcess);
}
}
BOOL terminate_process(HANDLE handle, UINT exitCode) {
TerminateProcess(handle, exitCode);
CloseHandle(handle);
return TRUE;
}
// Alternative (simplified), makes `std::bind` unnecessary:
BOOL alt_terminate_process(HANDLE handle) {
TerminateProcess(handle, 1);
CloseHandle(handle);
return TRUE;
}
int main()
{
for (int i = 0; i < 3; ++i) {
create_process();
}
std::this_thread::sleep_for(std::chrono::seconds{ 5 });
// use either
processes.erase(std::remove_if(processes.begin(), processes.end(), std::bind(terminate_process, std::placeholders::_1, 1)));
// or
processes.erase(std::remove_if(processes.begin(), processes.end(), alt_terminate_process));
return 0;
}