Windows/Linux下进程信息获取

news2024/11/29 18:28:33

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:

在这里插入图片描述


期待大家和我交流,留言或者私信,一起学习,一起进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPIO的输入模式

1. GPIO支持4种输入模式&#xff08;浮空输入、上拉输入、下拉输入、模拟输入&#xff09; 1. 模拟输入 首先GPIO输出部分(N-MOS,P-MOS)是不起作用的。并且TTL施密特触发器也是不工作的。 上下拉电阻的开关都是关闭的。相当于I/o直接接在模拟输入。 模拟输入模式下&#xff…

测试开源下载模块Downloader

微信公众号“DotNet”的文章《.NET 异步、跨平台、支持分段下载的开源项目 》&#xff08;参考文献1&#xff09;介绍了GitHub中的开源下载模块Downloader的基本用法&#xff0c;本文学习Downloader的主要参数设置方式及基本用法&#xff0c;最后编写简单的测试程序进行文件下载…

[尚硅谷React笔记]——第2章 React面向组件编程

目录&#xff1a; 基本理解和使用&#xff1a; 使用React开发者工具调试函数式组件复习类的基本知识类式组件组件三大核心属性1: state 复习类中方法this指向&#xff1a; 复习bind函数&#xff1a;解决changeWeather中this指向问题&#xff1a;一般写法&#xff1a;state.htm…

毛玻璃态计算器

效果展示 页面结构组成 从上述的效果可以看出&#xff0c;计算机的页面比较规整&#xff0c;适合grid布局。 CSS3 知识点 grid 布局 实现计算机布局 <div class"container"><form class"calculator" name"calc"><input type…

【无标题】ICCV 2023 | CAPEAM:基于上下文感知规划和环境感知记忆机制构建具身智能体

文章链接&#xff1a; https://arxiv.org/abs/2308.07241 2023年&#xff0c;大型语言模型&#xff08;LLMs&#xff09;以及AI Agents的蓬勃发展为整个机器智能领域带来了全新的发展机遇。一直以来&#xff0c;研究者们对具身智能&#xff08;Embodied Artificial Intelligenc…

macOS 14 Sonoma 如何删除不需要的 4k 动态壁纸

概览 在升级到 macOS 14&#xff08;Sonoma&#xff09;之后&#xff0c;小伙伴们惊喜发现  提供了诸多高清&#xff08;4k&#xff09;动态壁纸的支持。 现在&#xff0c;从锁屏到解锁进入桌面动态到静态的切换一气呵成、无比丝滑。 壁纸显现可谓是有了“天水相连为一色&…

卷发棒上架亚马逊美国销售需要做什么认证?卷发棒UL859测试报告

卷发棒是一种美发DIY工具&#xff0c;目前美发沙龙和发廊的的美发师都会使用一套卷发棒工具。卷发棒可以造出各种卷发。如&#xff1a;大波浪卷发、下垂自然卷发、垂至肩头卷发、碎卷、麦穗烫、内翻式卷发、外翻式卷发。目前很多家庭会自己备有这样的产品DIY。 什么是UL检测报告…

脉冲法和方向盘转角法计算车辆位置不同应用工况

1 脉冲法计算车辆位置 在定义下的世界坐标系中&#xff0c;车辆运动分为右转后退、右转前进、左转后退、左转前进、直线前进、直线后退和静止七种工况&#xff0c;因此需要推倒出一组包含脉冲、车辆运动方向和车辆结构尺寸参数的综合方程式进行车辆轨迹的实时迭代计算。由于直…

源码编译tcpreplay,及使用方法

编译步骤: 下载源码 解压 ./configure make sudo make install 使用方法: tcpreplay --loop1 --intf1网卡名 -x1 pcap文件名 实测结果: 左边是输入的tcpreplay命令 右边是tcpdump截获的udp包

你熟悉Docker吗?

你熟悉Docker吗&#xff1f; 文章目录 你熟悉Docker吗&#xff1f;快速入门Docker安装1.卸载旧版2.配置Docker的yum库3.安装Docker4.启动和校验5.配置镜像加速5.1.注册阿里云账号5.2.开通镜像服务5.3.配置镜像加速 部署MySQL镜像和容器命令解读 Docker基础常用命令数据卷数据卷…

Linux常见指令(1)

Linux常见指令[1] 一.前言1.操作系统简述 二.Linux常见指令1.登录Xshell2.Linux下的常见命令1.pwd2.ls1.ls -a2.ls -d3.ls -l 3.cd Linux中的文件系统1.文件的相关知识2.Linux下目录结构的认识1.什么叫做路径?2.Linux的整体目录结构3.为什么要有路径呢?4.绝对路径与相对路径 …

2023彩虹全新SUP模板,知识付费模板,卡卡云模板

源码介绍&#xff1a; 2023彩虹全新SUP模板/知识付费模板/卡卡云模板&#xff0c;首页美化&#xff0c;登陆页美化&#xff0c;修复了pc端购物车页面显示不正常的问题。 请自行查毒。感觉彩虹不少源码可能都有不干净的东西 安装教程&#xff1a; 1.将这俩个数据库文件导入数据…

队列的各个函数的实现

1.第一个结构是存放链表的数据&#xff0c;第二个结构体是存放头节点和尾节点的以方便找到尾节点&#xff0c;存放头节点的是phead&#xff0c;尾节点的是ptail typedef struct QueueNode {struct QueueNode* next;//单链表QDataType data;//放数据 }QNode;typedef struct Queu…

使用U3D、pico开发VR(二)——添加手柄摇杆控制移动

一、将unity 与visual studio 相关联 1.Edit->Preference->External tool 选择相应的版本 二、手柄遥控人物转向和人物移动 1.添加Locomotion System组件 选择XR Origin&#xff1b; 2.添加Continuous Move Provider&#xff08;Action-based&#xff09;组件 1>…

26962-2011 高频电磁场综合水处理器技术条件

声明 本文是学习GB-T 26962-2011 高频电磁场综合水处理器技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了高频电磁场综合水处理器(以下简称处理器)的术语和定义、分类和型号、结构型式、 要求及检验、标志、包装和贮运…

Opengl之抛光物

我们目前使用的光照都来自于空间中的一个点。它能给我们不错的效果,但现实世界中,我们有很多种类的光照,每种的表现都不同。将光投射(Cast)到物体的光源叫做投光物(Light Caster) 平行光 当一个光源处于很远的地方时,来自光源的每条光线就会近似于互相平行。不论物体和/或…

基于Java的会员管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【李沐深度学习笔记】图片分类数据集

课程地址和说明 图片分类数据集p3 本系列文章是我学习李沐老师深度学习系列课程的学习笔记&#xff0c;可能会对李沐老师上课没讲到的进行补充。本文还参考了【李沐3】3.5、图像分类数据集 图片分类数据集 MNIST数据集是图像分类中广泛使用的数据集之一&#xff0c;但作为基…

C语言——动态内存管理详解(内存结构、动态内存函数、易错题、柔性数组)

本篇概要 本篇文章从基本出发讲述为什么要存在动态内存分配&#xff0c;动态内存函数有哪些&#xff0c;常见的动态内存错误&#xff0c;一些关于内存分配的练习题以及柔性数组的相关知识。 文章目录 本篇概要1.为什么存在动态内存分配1.1为什么要动态分配内存1.2内存结构 2.常…

Unity实现设计模式——状态模式

Unity实现设计模式——状态模式 状态模式最核心的设计思路就是将对象的状态抽象出一个接口&#xff0c;然后根据它的不同状态封装其行为&#xff0c;这样就可以实现状态和行为的绑定&#xff0c;最终实现对象和状态的有效解耦。 在实际开发中一般用到FSM有限状态机的实现&…