Windows/Linux下进程信息获取
- 前言
- 一、windows部分
- 二、Linux部分
- 三、完整代码
- 四、结果
前言
Windows/Linux下进程信息获取,目前可获取进程名称、进程ID、进程状态
理论分析:
Windows版本获取进程列表的API:
-
CreateToolhelp32Snapshot()
- 创建进程快照,对应当前系统所有进程的实时状态。
- 参数TH32CS_SNAPPROCESS表示只捕获进程信息。
-
Process32First()
- 获取快照中第一个进程的ProcessEntry信息。
-
Process32Next()
- 循环获取快照中下一个进程的ProcessEntry信息。
-
PROCESSENTRY32
- 该结构体定义了每一个进程项的信息,如进程ID、名称等。
Linux版本获取进程列表的API:
-
opendir(“/proc”)
- 打开/proc文件夹,该文件夹下每个数字子目录对应一个进程。
-
readdir()
- 迭代读取/proc下的每个目录项。
-
DT_DIR
- 判断目录项类型,仅取子目录项。
-
stat文件
- 每个进程子目录下都有一个stat文件,包含进程状态信息。
详细分析:
-
Windows使用CreateToolhelp32Snapshot获取运行进程的快照。
-
通过Process32First和Process32Next依次遍历快照中的每个进程项。
-
获取进程项结构PROCESSENTRY32中的名称和ID字段。
-
Linux通过遍历/proc目录获取每个以数字为名的进程子目录。
-
判断子目录项类型后,打开每个子目录下的stat文件。
-
解析stat文件内容获取进程名称和状态。
一、windows部分
先稍微解析下:
std::vector<ProcessInfo> getRunningProcesses() {
std::vector<ProcessInfo> processList; // 进程信息向量
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 获取进程快照
if (snapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 processEntry; // 进程条目信息结构体
processEntry.dwSize = sizeof(PROCESSENTRY32); // 设置结构体大小
if (Process32First(snapshot, &processEntry)) { // 遍历快照中的第一个进程
do {
ProcessInfo processInfo; // 进程信息结构体
processInfo.name = processEntry.szExeFile; // 进程名称
processInfo.id = processEntry.th32ProcessID; // 进程ID
processInfo.status = "Running"; // 运行状态
processList.push_back(processInfo); // 加入向量
} while (Process32Next(snapshot, &processEntry)); // 遍历下一个进程
}
CloseHandle(snapshot); // 关闭快照
}
return processList; // 返回进程向量
}
二、Linux部分
std::vector<ProcessInfo> getRunningProcesses() {
std::vector<ProcessInfo> processList; // 定义进程信息向量
DIR* dir = opendir("/proc"); // 打开/proc目录
if (dir != nullptr) {
struct dirent* entry; // 定义目录条目结构体
while ((entry = readdir(dir)) != nullptr) { // 遍历目录条目
if (entry->d_type == DT_DIR) { // 如果是目录
std::string processDirName = entry->d_name; // 获取目录名
if (processDirName.find_first_not_of("0123456789") == std::string::npos) { // 如果目录名全是数字
std::string statFilePath = "/proc/" + processDirName + "/stat"; // 拼接状态文件路径
std::ifstream statFile(statFilePath); // 打开状态文件
if (statFile.is_open()) {
std::string name; // 进程名称
char status; // 进程状态
statFile >> name >> status; // 读取进程信息
ProcessInfo processInfo; // 定义进程信息结构体
processInfo.name = name.substr(1, name.length() - 2); // 获取进程名
processInfo.id = std::stoi(processDirName); // 获取进程ID
processInfo.status = (status == 'R') ? "Running" : "Idle"; // 获取状态
processList.push_back(processInfo); // 加入向量
}
}
}
}
closedir(dir); // 关闭目录
}
return processList; // 返回进程向量
}
三、完整代码
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include <string>
#ifdef _WIN32
#include <windows.h>
#include <tlhelp32.h>
#include <Psapi.h>
#else
#include <fstream>
#include <sstream>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/time.h>
#endif
struct ProcessInfo {
std::string name;
int id;
std::string status;
};
#ifdef _WIN32
std::vector<ProcessInfo> getRunningProcesses() {
std::vector<ProcessInfo> processList;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &processEntry)) {
do {
ProcessInfo processInfo;
processInfo.name = processEntry.szExeFile;
processInfo.id = processEntry.th32ProcessID;
processInfo.status = "Running";
processList.push_back(processInfo);
} while (Process32Next(snapshot, &processEntry));
}
CloseHandle(snapshot);
}
return processList;
}
#else
std::vector<ProcessInfo> getRunningProcesses() {
std::vector<ProcessInfo> processList;
DIR* dir = opendir("/proc");
if (dir != nullptr) {
struct dirent* entry;
while ((entry = readdir(dir)) != nullptr) {
if (entry->d_type == DT_DIR) {
std::string processDirName = entry->d_name;
if (processDirName.find_first_not_of("0123456789") == std::string::npos) {
std::string statFilePath = "/proc/" + processDirName + "/stat";
std::ifstream statFile(statFilePath);
if (statFile.is_open()) {
std::string name;
char status;
statFile >> name >> status;
ProcessInfo processInfo;
processInfo.name = name.substr(1, name.length() - 2);
processInfo.id = std::stoi(processDirName);
processInfo.status = (status == 'R') ? "Running" : "Idle";
processList.push_back(processInfo);
}
}
}
}
closedir(dir);
}
return processList;
}
#endif
void displayProcessInfo(const std::vector<ProcessInfo>& processList) {
for (const auto& process : processList) {
std::cout << "Process Name: " << process.name << std::endl;
std::cout << "Process ID: " << process.id << std::endl;
std::cout << "Process Status: " << process.status << std::endl;
std::cout << "-----------------------------" << std::endl;
}
}
int main() {
std::vector<ProcessInfo> processes = getRunningProcesses();
displayProcessInfo(processes);
#ifdef _WIN32
system("pause");
#endif
return 0;
}
四、结果
windows:
linux:
期待大家和我交流,留言或者私信,一起学习,一起进步!