我想获取我在C++中创建的每个进程的 PID,并在特定时间后终止每个进程



我是C++和Windows api的新手。我现在拥有的是我只能打印应用程序第一个进程的 PID。如果我要创建 4 个过程,我想得到他们的 PID;在控制台中打印它,并在特定时间(使用Chrono)后终止它们中的每一个。

示例概述:
1. for process=1 until process=5
2. Call notepad.exe3. Get the current PID of this process and print in the console.

4. Perform some execution from this processID5. increment process

6. Whoever successfully executed, terminate the PID.

这是我到目前为止的代码。

#include <iostream>
#include <string>
#include <tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
#include <stdlib.h>
using namespace std;
//  Forward declarations:
BOOL GetProcessList();
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode);

int main(void)
{
// Gives info on the thread and process for the new process
PROCESS_INFORMATION pif;
// Defines how to start the program
STARTUPINFO si;
// Zero the STARTUPINFO struct
ZeroMemory(&si, sizeof(si));
// Must set size of structure
si.cb = sizeof(si);
for (int i = 0; i < 3; i++) {
BOOL bRet = CreateProcess(L"C:\Users\notepad.exe", // Path to executable file
NULL,   // Command string - not needed here
NULL,   // Process handle not inherited
NULL,   // Thread handle not inherited
FALSE,  // No inheritance of handles
0,      // No special flags
NULL,   // Same environment block as this prog
NULL,   // Current directory - no separate path
&si,    // Pointer to STARTUPINFO
&pif); // Pointer to PROCESS_INFORMATION
if (FALSE == bRet)
{
MessageBox(HWND_DESKTOP, L"Unable to start program", L"", MB_OK);
return EXIT_FAILURE;
}
}
// Close handle to process
CloseHandle(pif.hProcess);
// Close handle to thread
CloseHandle(pif.hThread);
//return EXIT_SUCCESS;
//system("pause");
GetProcessList();
system("pause");
return 0;
}
BOOL GetProcessList()
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);  // clean the snapshot object
return(FALSE);
}
// Now walk the snapshot of processes 
do
{
//string str = pe32.szExeFile;
wchar_t *sample = pe32.szExeFile;
wstring ws(sample);
string str(ws.begin(), ws.end());
//cout << "Haha" << endl;
if (str == "notepad.exe") // put the name of your process you want to kill
{
//print the PID
cout << "n" <<pe32.th32ProcessID << endl;
system("pause");
TerminateMyProcess(pe32.th32ProcessID, 1);
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return(TRUE);
}
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL  bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, uExitCode);
CloseHandle(hProcess);
return result;
}

关于如何让同一应用程序的每个 PID 运行并同时终止它的任何想法?

由于PROCESS_INFORMATION pif包含DWORD dwProcessId中新创建的进程的id,例如,您可以通过将每个pif.dwProcessId添加到std::vector<DWORD> processIds来创建自己的列表。

要终止创建的进程,只需执行以下操作

for (auto processId : processIds) {
TerminateMyProcess(processId, 1);
}

编辑:

我想我刚刚意识到使用#include <algorithm>std::remove_if#include <functional>std::bind的改进。

而不是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显然有两个参数,DWORDUINT,我们可以将 std::bind 用作围绕TerminateMyProcess的包装函数,该函数接受一个DWORD参数(占位符::_1),而UINT设置为1

这样,成功终止的进程 ID 将从向量中删除,只留下无法终止的进程 ID。


另一个反映IInspctable评论的编辑:

在应用程序创建所有这些进程(示例中为记事本.exe)之后,每个进程都有一个特定的进程 ID。例如,想象一下,当您的应用程序等待终止这些进程的时间时,其中一个进程已经被终止。进程的 id 现在不再使用,操作系统可以将其分配给一个新的完全不同的进程,该进程与您的应用程序或记事本无关.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;
}

最新更新