使用C# winform 开发一个任务管理器

news2024/10/9 9:43:15

前言

为啥要开发这个呢 ,系统自带的关闭有些程序就关不了,它有好多线程,你关一其中一个它后台又重新开了一个,关不完,使用我这个呢 就把所有相同名称进程看作一个,一关就关

下载软件

v1


 

Form1.cs

using System;
using System.Windows.Forms;

namespace TaskMaster
{
    public partial class Form1 : Form
    {
        // 全局变量用于跟踪上次点击的列和排序方向
        private DataGridViewColumn lastSortedColumn;
        private SortOrder lastSortOrder = SortOrder.None;


        TaskManager taskManager;
        public Form1()
        {
            InitializeComponent();
            // 实例化 TaskManager
            taskManager = new TaskManager();

            //设置 DataGridView 的 Anchor 属性,确保它的大小会根据窗体的大小进行调整。你可以将 Anchor 设置为四个方向,使其随着窗口的拉伸或缩小进行动态调整。
            dataGridView1.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right);



            // 将进程信息加载到 dataGridView1
            taskManager.LoadProcessesIntoDataGridView(dataGridView1);


            // 绑定列头点击事件用于自定义排序
            dataGridView1.ColumnHeaderMouseClick += DataGridView_ColumnHeaderMouseClick;
        }

        /// <summary>
        /// 刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            // 将进程信息加载到 dataGridView1
            taskManager.LoadProcessesIntoDataGridView(dataGridView1);
        }


        /// <summary>
        /// 检查是否右键点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
        {
                    // 检查是否右键点击
            if (e.Button == MouseButtons.Right)
            {
                var hitTestInfo = dataGridView1.HitTest(e.X, e.Y);
                if (hitTestInfo.RowIndex >= 0)
                {
                    // 选中行
                    dataGridView1.Rows[hitTestInfo.RowIndex].Selected = true;

                    // 动态创建并显示上下文菜单
                    ContextMenuStrip contextMenu = new ContextMenuStrip();
                    ToolStripMenuItem closeProcessItem = new ToolStripMenuItem("关闭进程");
                    closeProcessItem.Click += CloseProcessItem_Click;

                    contextMenu.Items.Add(closeProcessItem);
                    contextMenu.Show(dataGridView1, e.Location);
                }
            }
        }

        /// <summary>
        /// 点击终止进程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CloseProcessItem_Click(object sender, EventArgs e)
        {
            // 获取选中行的进程名称
            if (dataGridView1.SelectedRows.Count > 0)
            {
                var selectedRow = dataGridView1.SelectedRows[0];
                string processName = selectedRow.Cells["ProcessName"].Value.ToString();

                // 终止进程
                taskManager.KillProcessesByName(processName);
                // 重新加载进程列表
                taskManager.LoadProcessesIntoDataGridView(dataGridView1);
            }
        }

        // 列头点击事件,用于自定义排序
        private void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            DataGridView dataGridView = sender as DataGridView;

            // 获取当前点击的列
            DataGridViewColumn clickedColumn = dataGridView.Columns[e.ColumnIndex];

            // 如果点击的是上次排序的列,切换排序方向
            SortOrder sortOrder;
            if (clickedColumn == lastSortedColumn)
            {
                sortOrder = lastSortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
            }
            else
            {
                // 如果是新列,默认升序排序
                sortOrder = SortOrder.Ascending;
            }

            // 根据列名执行不同的自定义排序逻辑
            if (clickedColumn.Name == "MemoryUsage")
            {
                dataGridView.Sort(new MemoryUsageComparer());
            }
            else if (clickedColumn.Name == "CpuTime")
            {
                dataGridView.Sort(new CpuTimeComparer());
            }
            else
            {
                // 默认的列使用内置排序
                dataGridView.Sort(clickedColumn, sortOrder == SortOrder.Ascending
                                  ? System.ComponentModel.ListSortDirection.Ascending
                                  : System.ComponentModel.ListSortDirection.Descending);
            }

            // 保存当前排序的列和方向
            lastSortedColumn = clickedColumn;
            lastSortOrder = sortOrder;
        }


    }




}

TaskManager.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace TaskMaster
{
    public class TaskManager
    {

        // 获取所有正在运行的进程并直接绑定到传入的 DataGridView
        public void LoadProcessesIntoDataGridView(DataGridView dataGridView)
        {
            // 清除现有的数据
            dataGridView.Rows.Clear();
            dataGridView.Columns.Clear();

            // 设置 DataGridView 属性
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dataGridView.AllowUserToAddRows = false;
            dataGridView.RowTemplate.Height = 50;

            // 创建一个新的 DataGridViewImageColumn
            DataGridViewImageColumn imageColumn = new DataGridViewImageColumn
            {
                HeaderText = "图标",
                Name = "IconColumn",
                ImageLayout = DataGridViewImageCellLayout.Normal
            };
            dataGridView.Columns.Add(imageColumn);

            // 添加其他数据列
            dataGridView.Columns.Add("ProcessName", "进程名");
            dataGridView.Columns.Add("PID", "进程ID");
            dataGridView.Columns.Add("MemoryUsage", "内存使用 (KB)");
            dataGridView.Columns.Add("CpuTime", "CPU时间");

            // 用于存储已经显示的进程名称
            HashSet<string> displayedProcesses = new HashSet<string>();

            // 获取所有进程
            Process[] processes = Process.GetProcesses();

            foreach (var process in processes)
            {
                try
                {
                    // 只显示尚未显示的进程
                    if (!displayedProcesses.Contains(process.ProcessName))
                    {
                        // 获取进程的可执行文件路径
                        string filePath = process.MainModule.FileName;

                        // 获取进程图标
                        Icon processIcon = GetProcessIcon(filePath);
                        Bitmap iconBitmap = processIcon.ToBitmap();

                        // 创建新行并设置图像及其他数据
                        int rowIndex = dataGridView.Rows.Add();
                        DataGridViewRow row = dataGridView.Rows[rowIndex];
                        row.Cells["IconColumn"].Value = iconBitmap;
                        row.Cells["ProcessName"].Value = process.ProcessName;
                        row.Cells["PID"].Value = process.Id;
                        row.Cells["MemoryUsage"].Value = FormatMemorySize(process.WorkingSet64);
                        row.Cells["CpuTime"].Value = FormatCpuTime(process.TotalProcessorTime);

                        // 记录已显示的进程名
                        displayedProcesses.Add(process.ProcessName);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"无法读取进程 {process.ProcessName}: {ex.Message}");
                }
            }
        }


        /// <summary>
        ///  格式化 CPU 时间,如果小时或分钟为 0 则不显示它们
        /// </summary>
        /// <param name="cpuTime"></param>
        /// <returns></returns>
        private string FormatCpuTime(TimeSpan cpuTime)
        {
            int hours = cpuTime.Hours;
            int minutes = cpuTime.Minutes;
            int seconds = cpuTime.Seconds;
            int milliseconds = cpuTime.Milliseconds;

            // 使用 StringBuilder 动态构建时间字符串
            StringBuilder formattedTime = new StringBuilder();

            if (hours > 0)
            {
                formattedTime.Append($"{hours}H");
            }
            if (minutes > 0 || hours > 0) // 如果有小时,即使分钟为 0 也显示
            {
                formattedTime.Append($"{minutes}M");
            }
            if (seconds > 0 || minutes > 0 || hours > 0) // 如果有分钟或小时,即使秒为 0 也显示
            {
                formattedTime.Append($"{seconds}S");
            }
            // 毫秒总是显示
            formattedTime.Append($"{milliseconds}MS");

            return formattedTime.ToString();
        }



        /// <summary>
        /// 将内存大小转换为合适的单位
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        private string FormatMemorySize(long bytes)
        {
            const double KB = 1024;
            const double MB = KB * 1024;
            const double GB = MB * 1024;

            if (bytes >= GB)
            {
                return $"{(bytes / GB):F2} GB";
            }
            else if (bytes >= MB)
            {
                return $"{(bytes / MB):F2} MB";
            }
            else if (bytes >= KB)
            {
                return $"{(bytes / KB):F2} KB";
            }
            else
            {
                return $"{bytes} B";
            }
        }

        /// <summary>
        /// 获取进程图标
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private Icon GetProcessIcon(string filePath)
        {
            try
            {
                // 使用 Icon.ExtractAssociatedIcon 方法获取文件图标
                return Icon.ExtractAssociatedIcon(filePath);
            }
            catch
            {
                // 如果获取图标失败,返回一个默认图标
                return SystemIcons.Application; // 使用默认图标
            }
        }


        // 根据进程 ID 终止进程
        public bool KillProcess(int processId)
        {
            try
            {
                Process process = Process.GetProcessById(processId);
                process.Kill();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"无法终止进程 {processId}: {ex.Message}");
                return false;
            }
        }

        // 根据进程名称终止所有匹配的进程
        public bool KillProcessesByName(string processName)
        {
            try
            {
                // 查找所有与指定名称匹配的进程
                Process[] processes = Process.GetProcessesByName(processName);

                if (processes.Length == 0)
                {
                    Console.WriteLine($"没有找到名为 {processName} 的进程。");
                    return false;
                }

                // 终止所有匹配的进程
                foreach (var process in processes)
                {
                    process.Kill();
                }

                Console.WriteLine($"已终止所有名为 {processName} 的进程。");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"无法终止进程 {processName}: {ex.Message}");
                return false;
            }
        }
    }
}

工程源码

v1

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

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

相关文章

learn C++ NO.21——AVL树

简单介绍一下AVL树 AVL树是一种自平衡的二叉搜索树&#xff08;Balanced Binary Search Tree, BBST&#xff09;&#xff0c;由俄罗斯数学家G. M. Adelson-Velsky和E. M. Landis在1962年发明&#xff0c;因此以其名字首字母命名。AVL树通过保持任何节点的两个子树的高度最大差…

养生健康:从日常细节中寻觅长寿之钥

养生健康&#xff1a;从日常细节中寻觅长寿之钥 在这个快节奏的时代&#xff0c;健康似乎成了一种奢侈品&#xff0c;但实则不然。养生之道&#xff0c;不在于繁复的仪式&#xff0c;而在于融入日常的点点滴滴。今天&#xff0c;就让我们一起探讨几个简单却至关重要的养生习惯…

N1从安卓盒子刷成armbian

Release Armbian_noble_save_2024.10 ophub/amlogic-s9xxx-armbian (github.com) armbian下载&#xff0c;这里要选择905d adb 下载地址 https://dl.google.com/android/repository/platform-tools-latest-windows.zip 提示信息 恩山无线论坛 使用usb image tool restet a…

Java项目实战II基于Java+Spring Boot+MySQL的高校学科竞赛平台

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着高等教…

【Vue】Vue 快速教程

Vue tutorial 参考&#xff1a;教程 | Vue.js (vuejs.org) 该教程需要前置知识&#xff1a;HTML, CSS, JavaScript 学习前置知识&#xff0c;你可以去 MDN Vue framework 是一个 JavaScript framework&#xff0c;以下简称 Vue&#xff0c;下面是它的特点 声明式渲染&#xff…

音频进阶学习三——离散时间信号与系统

文章目录 前言一、离散时间信号1.基本信号2.离散时间信号的分类3.离散时间信号的简单运算4.单位脉冲在运算中的作用 二、离散时间系统1.什么是离散时间系统2.离散系统的分类 总结 前言 前面博主介绍了信号中的连续时间信号和离散时间信号&#xff0c;数字信号也是离散时间信号…

1.一、MyBatis入门

一、MyBatis入门 我们做为后端程序开发人员&#xff0c;通常会使用Java程序来完成对数据库的操作。Java程序操作数据库&#xff0c;现在主流的方式是&#xff1a;Mybatis。 一、什么是MyBatis? MyBatis官网的解释&#xff1a; MyBatis 是一款优秀的持久层框架&#xff0c;它…

基于Zabbix进行服务器运行情况监测

文章目录 引言I Zabbix主要构成下载并安装Zabbix被监控主机安装zabbix agent创建被监控主机报警设置II 常见问题cannot use database "zabbix": its "users" table is empty (is this the Zabbix proxy database?)重置 Zabbix Web 界面密码Zabbix agent i…

【c++】初步了解类和对象2

1、类的作用域 类定义了一个新的作用域&#xff0c;类的所有成员都在类的作用域中。在类体外定义成员时&#xff0c;需要使用 :: 作用域操作符指明成员属于哪个类域。 如图&#xff0c;此时在类内声明了函数firstUniqChar()&#xff0c;在类外进行了函数体的具体定义。 但是却…

【成神之路】Ambari实战-050-UI-如何通过配置修改ambari样式

在Ambari中&#xff0c;通过自定义UI控件&#xff08;Widget&#xff09;&#xff0c;你可以灵活调整配置项的展现形式&#xff0c;使其更符合实际需求。这篇文章将详细介绍各种控件的使用&#xff0c;并提供代码示例和实际应用场景&#xff0c;帮助你成为UI配置的行家&#xf…

国家发改委等部门划时间点:到2026年底基本建成国家数据标准体系

摘要 【国家发改委等部门划时间点&#xff1a;到2026年底基本建成国家数据标准体系】10月8日&#xff0c;国家发改委等部门联合印发《国家数据标准体系建设指南》。《建设指南》提出计划&#xff0c;到2026年底&#xff0c;基本建成国家数据标准体系&#xff0c;围绕数据流通利…

jmeter学习(7)beanshell

beanshell preprocessor 发送请求前执行 beanshell postprocessor 发送请求前执行 获取请求相关信息 String body sampler.getArguments().getArgument(0).getValue(); String url sampler.getPath(); 获取响应报文 String responseprev.getResponseDataAsString(); 获…

应急响应:LinuxWindows实战排查

目录 应急响应 介绍&#xff1a; 应急流程&#xff1a; 抑制阶段&#xff1a; 对于Linux&#xff0c;一些常见的排查命令&#xff1a; 对于Windows&#xff0c;常见的排查命令&#xff1a; Windows应急&#xff08;一&#xff09; Windows应急&#xff08;二&#xff0…

C++ string类(超详细一次性讲解)(上)

1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 C语言中&#xff0c;字符串是以 \0 结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&…

Python OpenCV精讲系列 - 三维重建深入理解(十七)

&#x1f496;&#x1f496;⚡️⚡️专栏&#xff1a;Python OpenCV精讲⚡️⚡️&#x1f496;&#x1f496; 本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计&#xff0c;从基础概念入手&#xff0c;逐步深入到图像处理、特征检测、物体识…

细菌实例分割系统源码&数据集分享

细菌实例分割系统源码&#xff06;数据集分享 [yolov8-seg-EfficientFormerV2&#xff06;yolov8-seg-SPPF-LSKA等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glob…

系分-数据库总结

历年试题2024年05月试题 BCN范式&#xff0c;模式分解&#xff0c;触发器类型2023年05月试题 NoSQL基本特点&#xff0c;NoSQL对比&#xff0c;混合数据库2022年05月试题4 两段锁&#xff0c;事务并发&#xff0c;数据一致&#xff0c;本地事务发布20…

生命的最高境界(深度好文)?

予人玫瑰&#xff0c;手有余香。 生命的最高境界&#xff0c;就一个字&#xff1a;给。 初级的快乐&#xff0c;是放任&#xff1b;中级的快乐&#xff0c;是自律&#xff1b;高级的快乐&#xff0c;是给予。 予人玫瑰&#xff0c;手有余香。 学会“给”&#xff0c;是我们一…

PCL 表面曲率下采样

目录 一、概述二、代码三、结果 一、概述 通过表面曲率信息对点云进行采样&#xff0c;选择表面曲率约束下的代表性点。 二、代码 #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h&g…

《Python 安装指南:开启编程之旅》

《Python 安装指南&#xff1a;开启编程之旅》 在当今数字化的时代&#xff0c;编程已经成为一项越来越重要的技能。而 Python 作为一种简洁、高效且功能强大的编程语言&#xff0c;受到了众多开发者的青睐。无论是数据科学、人工智能、Web 开发还是自动化脚本编写&#xff0c…