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

前言

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

下载软件

v1

Form1.cs

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

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

相关推荐
YMWM_5 分钟前
第一章 Go语言简介
开发语言·后端·golang
只因在人海中多看了你一眼6 分钟前
python语言基础
开发语言·python
2401_858286118 分钟前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
y25089 分钟前
《Object类》
java·开发语言
小技与小术13 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
hccee35 分钟前
C# IO文件操作
开发语言·c#
hummhumm40 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊1 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
zmd-zk1 小时前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang