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

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

 

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

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

我们初始设置为300行

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

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

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

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

tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);

然后我们设置一个接口

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

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

#include <windows.h>
#include <tlhelp32.h>

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

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

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

pe.dwSize = sizeof(pe);

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

这里介绍一下

CreateToolhelp32Snapshot函数

原型:

HANDLE WINAPI CreateToolhelp32Snapshot(
  _In_ DWORD dwFlags,       //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
  _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++;
        }

void Widget::showProess()
    {

        PROCESSENTRY32 pe;
          //在使用这个结构前,先设置它的大小
          pe.dwSize = sizeof(pe);


        //获取进程信息的链表
        HANDLE hSnopShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if(hSnopShot==INVALID_HANDLE_VALUE)
            return ;
        //获取链表的头
        bool bFlag= Process32First(hSnopShot,&pe);
        int i=0;
        QString str;
        //遍历链表
        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++;
        }




    }

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

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

具体步骤:

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

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

void on_pushButton_clicked()

在槽函数中

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

 

 //获取当前进程id
        QList<QTableWidgetItem*>listitem=ui->tableWidget->selectedItems();

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

        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类的完整代码如下

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <windows.h>
#include <tlhelp32.h>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void showProess();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
    #include "widget.h"
    #include "ui_widget.h"
    #include "QTableWidget"
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        ui->tableWidget->setSelectionMode(QTableWidget::SingleSelection);
        ui->tableWidget->setSelectionBehavior(QTableWidget::SelectRows);
        showProess();
    }

    Widget::~Widget()
    {
        delete ui;
    }


    void Widget::showProess()
    {

        PROCESSENTRY32 pe;
          //在使用这个结构前,先设置它的大小
          pe.dwSize = sizeof(pe);


        //获取进程信息的链表
        HANDLE hSnopShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if(hSnopShot==INVALID_HANDLE_VALUE)
            return ;
        //获取链表的头
        bool bFlag= Process32First(hSnopShot,&pe);
        int i=0;
        QString str;
        //遍历链表
        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++;
        }




    }

    void Widget::on_pushButton_clicked()
    {
        //获取当前进程id
        QList<QTableWidgetItem*>listitem=ui->tableWidget->selectedItems();

        QTableWidgetItem*pitem=listitem.front();
        int nrow=ui->tableWidget->row(pitem);
        listitem.pop_front();
        pitem=listitem.front();
        listitem.pop_front();
        QString strid=pitem->text();
        if(strid.isEmpty())
            return ;
        //获取句柄

         HANDLE hProcess= OpenProcess(PROCESS_TERMINATE,0,strid.toInt());
        //杀死进程
         if(hProcess)
         {
             TerminateProcess(hProcess,-1);
             ui->tableWidget->removeRow(nrow);
         }


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值