• 操作系统小练习 任务管理器


    首先 我们还是在QT编译器下进行

     

    我们在widget窗口下创建这样一个界面

     是一个TableWidget表格  包含了进程名称  进程id 线程数这几个数据

    我们初始设置为300行

    同时 我们设置了一个按钮  来控制结束进程的操作

    首先  我们在Widget的构造函数中

    为这个表格设置单行选择的行为
     ui->tableWidget->setSelectionBehavior(QTableWidget::SelectRows);

    同时又不想让他支持Ctrl、Shift、 Ctrl+A等操作方法

    tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);

    然后我们设置一个接口

    showProess()用来将我门的进程显示在表格中

    我们如果想或渠道系统的进程  需要先引入头文件

    #include
    #include

    然后再接口函数void showProess();中进行操作

    先定义一个PROCESSENTRY32 类型的结构体pe

    然后对结构体的大小进行设置

    pe.dwSize = sizeof(pe);

    之后我们用到了CreateToolhelp32Snapshot函数来获取进程信息的链表

    这里介绍一下

    CreateToolhelp32Snapshot函数

    原型:

    1. HANDLE WINAPI CreateToolhelp32Snapshot(
    2.   _In_ DWORD dwFlags,       //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
    3.   _In_ DWORD th32ProcessID  //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0

    参数1:

    要包含在快照中的系统部分。此参数可以是以下一个或多个值。

    价值意义

    TH32CS_INHERIT

    0x80000000

    指示快照句柄是可继承的。

    TH32CS_SNAPALL

    包括系统中的所有进程和线程,以及 th32ProcessID 中指定的进程的堆和模块。等效于指定使用 OR 运算组合的TH32CS_SNAPHEAPLISTTH32CS_SNAPMODULETH32CS_SNAPPROCESS和TH32CS_SNAPTHREAD值(“|”)。

    TH32CS_SNAPHEAPLIST

    0x00000001

    包括快照中 th32ProcessID 中指定的进程的所有堆。若要枚举堆,请参阅 Heap32ListFirst

    TH32CS_SNAPMODULE

    0x00000008

    包括快照中 th32ProcessID 中指定的进程的所有模块。要枚举模块,请参阅 Module32First。如果函数失败并ERROR_BAD_LENGTH,请重试该函数,直到成功为止。

    64 位窗口: 在 32 位进程中使用此标志包括 th32ProcessID 中指定的进程的 32 位模块,而在 64 位进程中使用此标志包括 64 位模块。要从 64 位进程中包括 th32ProcessID 中指定的进程的 32 位模块,请使用 TH32CS_SNAPMODULE32 标志。

    TH32CS_SNAPMODULE32

    0x00000010

    从 64 位进程调用时,在快照中包括 th32ProcessID 中指定的进程的所有 32 位模块。此标志可以与TH32CS_SNAPMODULETH32CS_SNAPALL结合使用。如果函数失败并ERROR_BAD_LENGTH,请重试该函数,直到成功为止。

    TH32CS_SNAPPROCESS

    0x00000002

    在快照中包括系统中的所有进程。若要枚举进程,请参阅进程 32First

    TH32CS_SNAPTHREAD

    0x00000004

    在快照中包括系统中的所有线程。要枚举线程,请参阅 Thread32First

    要标识属于特定进程的线程,请在枚举线程时将其进程标识符与 THREADENTRY32 结构的 th32OwnerProcessID 成员进行比较。

    );

    参数2:

    [in] th32ProcessID

    要包含在快照中的进程的进程标识符。此参数可以为零,以指示当前进程。当指定了TH32CS_SNAPHEAPLIST、TH32CS_SNAPMODULE、TH32CS_SNAPMODULE32或TH32CS_SNAPALL值时,将使用此参数。否则,将忽略它,并将所有进程都包含在快照中。

    如果指定的进程是空闲进程或 CSRSS 进程之一,则此函数将失败,并且ERROR_ACCESS_DENIED最后一个错误代码,因为它们的访问限制会阻止用户级代码打开它们。

    如果指定的进程是 64 位进程,而调用方是 32 位进程,则此函数将失败,并且最后一个错误代码为 ERROR_PARTIAL_COPY (299)。

          返回值

    如果函数成功,它将返回指定快照的打开句柄。

    如果函数失败,它将返回INVALID_HANDLE_VALUE。若要获取扩展的错误信息,请调用 GetLastError。可能的错误代码包括ERROR_BAD_LENGTH

    在介绍一下

    process32First()

    是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用process32First函数来获得第一个进程的句柄.

    这里我们添加了一个

    HANDLE  hSnopShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    用hSnopShot来记录句柄

    在定义一个bFlag来记录bool bFlag= Process32First(hSnopShot,&pe);

    判断我们获取到的链表的头是否为空

    process32Next()

    判断我们获取到的链表的节点的下一个是否为空

    之后遍历  

    往表格上写:

    pe.szExeFile:进程名称

    pe.th32ProcessID:进程ID

    pe.cntThreads:线程数

     while(bFlag)
            {
                //name
                str=QString::fromWCharArray(pe.szExeFile);
                ui->tableWidget->setItem(i,0,new QTableWidgetItem(str));

                //process
                str=QString::number(pe.th32ProcessID);
                 ui->tableWidget->setItem(i,1,new QTableWidgetItem(str));


                str=QString::number(pe.cntThreads);
                 ui->tableWidget->setItem(i,2,new QTableWidgetItem(str));

                 bFlag=Process32Next(hSnopShot,&pe);
                 i++;
            }

    1. void Widget::showProess()
    2. {
    3. PROCESSENTRY32 pe;
    4. //在使用这个结构前,先设置它的大小
    5. pe.dwSize = sizeof(pe);
    6. //获取进程信息的链表
    7. HANDLE hSnopShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    8. if(hSnopShot==INVALID_HANDLE_VALUE)
    9. return ;
    10. //获取链表的头
    11. bool bFlag= Process32First(hSnopShot,&pe);
    12. int i=0;
    13. QString str;
    14. //遍历链表
    15. while(bFlag)
    16. {
    17. //name
    18. str=QString::fromWCharArray(pe.szExeFile);
    19. ui->tableWidget->setItem(i,0,new QTableWidgetItem(str));
    20. //process
    21. str=QString::number(pe.th32ProcessID);
    22. ui->tableWidget->setItem(i,1,new QTableWidgetItem(str));
    23. str=QString::number(pe.cntThreads);
    24. ui->tableWidget->setItem(i,2,new QTableWidgetItem(str));
    25. bFlag=Process32Next(hSnopShot,&pe);
    26. i++;
    27. }
    28. }

    这样一来  我们就获取到了系统的进程  并写到了表格中

    之后 我们开始对杀死进程这一功能进行编写

    具体步骤:

    点击想要删除的行  点击杀死进程  进程结束  表格中该进程消失

    首先对按钮"杀死进程"添加一个槽函数

    void on_pushButton_clicked()

    在槽函数中

    我们要先获得当前选中的进程的id 

     

     //获取当前进程id
            QListlistitem=ui->tableWidget->selectedItems();

    //定义一个QList类型的列表来存我们当前在表格中选中的一行的数据;

            QTableWidgetItem*pitem=listitem.front();

            int nrow=ui->tableWidget->row(pitem);

    //定义一个nrow记录当前选中的行
            listitem.pop_front();
            pitem=listitem.front();

    //在定义一个 QTableWidgetItem*类型的节点用来寻找进程ID  我们这里的ID是第二列

    所以pitem记录了第二列

            listitem.pop_front();

    QString strid=pitem->text();

    strid记录了第二列的字符串;

     

     if(strid.isEmpty())
                return ;
            //获取句柄

             HANDLE hProcess= OpenProcess(PROCESS_TERMINATE,0,strid.toInt());
            //杀死进程
             if(hProcess)
             {
                 TerminateProcess(hProcess,-1);


                 ui->tableWidget->removeRow(nrow);
             }

    Widget类的完整代码如下

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include
    5. #include
    6. QT_BEGIN_NAMESPACE
    7. namespace Ui { class Widget; }
    8. QT_END_NAMESPACE
    9. class Widget : public QWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. Widget(QWidget *parent = nullptr);
    14. ~Widget();
    15. void showProess();
    16. private slots:
    17. void on_pushButton_clicked();
    18. private:
    19. Ui::Widget *ui;
    20. };
    21. #endif // WIDGET_H
    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. #include "QTableWidget"
    4. Widget::Widget(QWidget *parent)
    5. : QWidget(parent)
    6. , ui(new Ui::Widget)
    7. {
    8. ui->setupUi(this);
    9. ui->tableWidget->setSelectionMode(QTableWidget::SingleSelection);
    10. ui->tableWidget->setSelectionBehavior(QTableWidget::SelectRows);
    11. showProess();
    12. }
    13. Widget::~Widget()
    14. {
    15. delete ui;
    16. }
    17. void Widget::showProess()
    18. {
    19. PROCESSENTRY32 pe;
    20. //在使用这个结构前,先设置它的大小
    21. pe.dwSize = sizeof(pe);
    22. //获取进程信息的链表
    23. HANDLE hSnopShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    24. if(hSnopShot==INVALID_HANDLE_VALUE)
    25. return ;
    26. //获取链表的头
    27. bool bFlag= Process32First(hSnopShot,&pe);
    28. int i=0;
    29. QString str;
    30. //遍历链表
    31. while(bFlag)
    32. {
    33. //name
    34. str=QString::fromWCharArray(pe.szExeFile);
    35. ui->tableWidget->setItem(i,0,new QTableWidgetItem(str));
    36. //process
    37. str=QString::number(pe.th32ProcessID);
    38. ui->tableWidget->setItem(i,1,new QTableWidgetItem(str));
    39. str=QString::number(pe.cntThreads);
    40. ui->tableWidget->setItem(i,2,new QTableWidgetItem(str));
    41. bFlag=Process32Next(hSnopShot,&pe);
    42. i++;
    43. }
    44. }
    45. void Widget::on_pushButton_clicked()
    46. {
    47. //获取当前进程id
    48. QListlistitem=ui->tableWidget->selectedItems();
    49. QTableWidgetItem*pitem=listitem.front();
    50. int nrow=ui->tableWidget->row(pitem);
    51. listitem.pop_front();
    52. pitem=listitem.front();
    53. listitem.pop_front();
    54. QString strid=pitem->text();
    55. if(strid.isEmpty())
    56. return ;
    57. //获取句柄
    58. HANDLE hProcess= OpenProcess(PROCESS_TERMINATE,0,strid.toInt());
    59. //杀死进程
    60. if(hProcess)
    61. {
    62. TerminateProcess(hProcess,-1);
    63. ui->tableWidget->removeRow(nrow);
    64. }
    65. }

  • 相关阅读:
    利用Jmeter做接口测试(功能测试)全流程分析
    【水果派不吃灰】Raspberry Pi树莓派Linux系统下替换国内apt软件更新源
    vue3--计算属性
    完完整整地看完这个故事,你敢说还不懂Docker?
    【Python】 -- 字典get()函数的用法
    dreamweaver作业静态HTML网页设计——家乡海南旅游网站
    Spring Boot 中的 TransactionTemplate 是什么,如何使用
    FFmpeg入门详解之122:Qt5 FFmpeg本地摄像头采集预览实战
    [代码随想录]二叉树篇
    Day45——视图,触发器,事务,存储过程
  • 原文地址:https://blog.csdn.net/van9527/article/details/126137943